stm32f4/stm32f401rc-rs485: add support to userleds

This commit is contained in:
Rodrigo Sim 2023-11-11 16:44:03 -03:00 committed by Xiang Xiao
parent 0d42f1b3cf
commit 66ccaed5ce
6 changed files with 262 additions and 11 deletions

View File

@ -36,9 +36,8 @@
/* Clocking *****************************************************************/ /* Clocking *****************************************************************/
/* The STM32F401RC-RS485 supports both HSE and LSE crystals (X2 and X3). /* The STM32F401RC-RS485 uses an external 32kHz cristal (X2) to enable HSE
* However, as shipped, the X2 and X3 crystals are not populated. * clock.
* Therefore the Nucleo-F401RE will need to run off the 16MHz HSI clock.
* *
* System Clock source : PLL (HSI) * System Clock source : PLL (HSI)
* SYSCLK(Hz) : 84000000 Determined by PLL * SYSCLK(Hz) : 84000000 Determined by PLL
@ -335,22 +334,26 @@ extern "C"
/* LEDs /* LEDs
* *
* The Nucleo F401RE and F411RE boards provide a single user LED, LD2. LD2 * The STM32F401RC-RS485 boards provide 4 blue user LEDs. LD1, LD2, LD3
* is the green LED connected to Arduino signal D13 corresponding to MCU I/O * and LD4 that are connected to MCU I/O pins PC0, PC1, PC2 and PC3.
* PA5 (pin 21) or PB13 (pin 34) depending on the STM32 target.
*
* - When the I/O is HIGH value, the LED is on. * - When the I/O is HIGH value, the LED is on.
* - When the I/O is LOW, the LED is off. * - When the I/O is LOW, the LED is off.
*/ */
/* LED index values for use with board_userled() */ /* LED index values for use with board_userled() */
#define BOARD_LD2 0 #define BOARD_LD1 0
#define BOARD_NLEDS 1 #define BOARD_LD2 1
#define BOARD_LD3 2
#define BOARD_LD4 3
#define BOARD_NLEDS 4
/* LED bits for use with board_userled_all() */ /* LED bits for use with board_userled_all() */
#define BOARD_LD2_BIT (1 << BOARD_LD2) #define BOARD_LED1_BIT (1 << BOARD_LD1)
#define BOARD_LED2_BIT (1 << BOARD_LD2)
#define BOARD_LED3_BIT (1 << BOARD_LD3)
#define BOARD_LED4_BIT (1 << BOARD_LD4)
/* These LEDs are not used by the board port unless CONFIG_ARCH_LEDS is /* These LEDs are not used by the board port unless CONFIG_ARCH_LEDS is
* defined. In that case, the usage by the board port is defined in * defined. In that case, the usage by the board port is defined in

View File

@ -24,6 +24,10 @@ if(CONFIG_ARCH_LEDS)
list(APPEND SRCS stm32_autoleds.c) list(APPEND SRCS stm32_autoleds.c)
endif() endif()
if(CONFIG_USERLED)
list(APPEND SRCS stm32_userleds.c)
endif()
if(CONFIG_BOARDCTL) if(CONFIG_BOARDCTL)
list(APPEND SRCS stm32_appinit.c) list(APPEND SRCS stm32_appinit.c)
endif() endif()

View File

@ -27,6 +27,10 @@ ifeq ($(CONFIG_ARCH_LEDS),y)
CSRCS += stm32_autoleds.c CSRCS += stm32_autoleds.c
endif endif
ifeq ($(CONFIG_USERLED),y)
CSRCS += stm32_userleds.c
endif
ifeq ($(CONFIG_BOARDCTL),y) ifeq ($(CONFIG_BOARDCTL),y)
CSRCS += stm32_appinit.c CSRCS += stm32_appinit.c
endif endif

View File

@ -35,6 +35,10 @@
#include <arch/board/board.h> #include <arch/board/board.h>
#ifdef CONFIG_USERLED
# include <nuttx/leds/userled.h>
#endif
#include "stm32f401rc-rs485.h" #include "stm32f401rc-rs485.h"
#include <nuttx/board.h> #include <nuttx/board.h>
@ -61,5 +65,15 @@ int stm32_bringup(void)
{ {
int ret = OK; int ret = OK;
#ifdef CONFIG_USERLED
/* Register the LED driver */
ret = userled_lower_initialize("/dev/userleds");
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: userled_lower_initialize() failed: %d\n", ret);
}
#endif
return ret; return ret;
} }

View File

@ -0,0 +1,214 @@
/****************************************************************************
* boards/arm/stm32/stm32f401rc-rs485/src/stm32_userleds.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 <stdbool.h>
#include <debug.h>
#include <nuttx/board.h>
#include <nuttx/power/pm.h>
#include <arch/board/board.h>
#include "chip.h"
#include "arm_internal.h"
#include "stm32.h"
#include "stm32f401rc-rs485.h"
#ifndef CONFIG_ARCH_LEDS
/****************************************************************************
* Private Data
****************************************************************************/
/* This array maps an LED number to GPIO pin configuration */
static uint32_t g_ledcfg[BOARD_NLEDS] =
{
GPIO_LED1, GPIO_LED2, GPIO_LED3, GPIO_LED4
};
/****************************************************************************
* Private Function Protototypes
****************************************************************************/
/* LED Power Management */
#ifdef CONFIG_PM
static void led_pm_notify(struct pm_callback_s *cb, int domain,
enum pm_state_e pmstate);
static int led_pm_prepare(struct pm_callback_s *cb, int domain,
enum pm_state_e pmstate);
#endif
/****************************************************************************
* Private Data
****************************************************************************/
#ifdef CONFIG_PM
static struct pm_callback_s g_ledscb =
{
.notify = led_pm_notify,
.prepare = led_pm_prepare,
};
#endif
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: led_pm_notify
*
* Description:
* Notify the driver of new power state. This callback is called after
* all drivers have had the opportunity to prepare for the new power state.
*
****************************************************************************/
#ifdef CONFIG_PM
static void led_pm_notify(struct pm_callback_s *cb, int domain,
enum pm_state_e pmstate)
{
switch (pmstate)
{
case(PM_NORMAL):
{
/* Restore normal LEDs operation */
}
break;
case(PM_IDLE):
{
/* Entering IDLE mode - Turn leds off */
}
break;
case(PM_STANDBY):
{
/* Entering STANDBY mode - Logic for PM_STANDBY goes here */
}
break;
case(PM_SLEEP):
{
/* Entering SLEEP mode - Logic for PM_SLEEP goes here */
}
break;
default:
{
/* Should not get here */
}
break;
}
}
#endif
/****************************************************************************
* Name: led_pm_prepare
*
* Description:
* Request the driver to prepare for a new power state. This is a warning
* that the system is about to enter into a new power state. The driver
* should begin whatever operations that may be required to enter power
* state. The driver may abort the state change mode by returning a
* non-zero value from the callback function.
*
****************************************************************************/
#ifdef CONFIG_PM
static int led_pm_prepare(struct pm_callback_s *cb, int domain,
enum pm_state_e pmstate)
{
/* No preparation to change power modes is required by the LEDs driver.
* We always accept the state change by returning OK.
*/
return OK;
}
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: board_userled_initialize
****************************************************************************/
uint32_t board_userled_initialize(void)
{
/* Configure LED1-4 GPIOs for output */
stm32_configgpio(GPIO_LED1);
stm32_configgpio(GPIO_LED2);
stm32_configgpio(GPIO_LED3);
stm32_configgpio(GPIO_LED4);
return BOARD_NLEDS;
}
/****************************************************************************
* Name: board_userled
****************************************************************************/
void board_userled(int led, bool ledon)
{
if ((unsigned)led < BOARD_NLEDS)
{
stm32_gpiowrite(g_ledcfg[led], ledon);
}
}
/****************************************************************************
* Name: board_userled_all
****************************************************************************/
void board_userled_all(uint32_t ledset)
{
stm32_gpiowrite(GPIO_LED1, (ledset & BOARD_LED1_BIT) != 0);
stm32_gpiowrite(GPIO_LED2, (ledset & BOARD_LED2_BIT) != 0);
stm32_gpiowrite(GPIO_LED3, (ledset & BOARD_LED3_BIT) != 0);
stm32_gpiowrite(GPIO_LED4, (ledset & BOARD_LED4_BIT) != 0);
}
/****************************************************************************
* Name: stm32_led_pminitialize
****************************************************************************/
#ifdef CONFIG_PM
void stm32_led_pminitialize(void)
{
/* Register to receive power management callbacks */
int ret = pm_register(&g_ledscb);
if (ret != OK)
{
board_autoled_on(LED_ASSERTION);
}
}
#endif /* CONFIG_PM */
#endif /* !CONFIG_ARCH_LEDS */

View File

@ -51,7 +51,19 @@
*/ */
#define GPIO_LED1 \ #define GPIO_LED1 \
(GPIO_PORTC | GPIO_PIN0 | GPIO_OUTPUT_CLEAR | GPIO_OUTPUT | GPIO_PULLUP | \ (GPIO_PORTC | GPIO_PIN0 | GPIO_OUTPUT_CLEAR | GPIO_OUTPUT | \
GPIO_SPEED_50MHz)
#define GPIO_LED2 \
(GPIO_PORTC | GPIO_PIN1 | GPIO_OUTPUT_CLEAR | GPIO_OUTPUT | \
GPIO_SPEED_50MHz)
#define GPIO_LED3 \
(GPIO_PORTC | GPIO_PIN2 | GPIO_OUTPUT_CLEAR | GPIO_OUTPUT | \
GPIO_SPEED_50MHz)
#define GPIO_LED4 \
(GPIO_PORTC | GPIO_PIN3 | GPIO_OUTPUT_CLEAR | GPIO_OUTPUT | \
GPIO_SPEED_50MHz) GPIO_SPEED_50MHz)
/* Buttons /* Buttons