This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 66ccaed5ce stm32f4/stm32f401rc-rs485: add support to userleds
66ccaed5ce is described below
commit 66ccaed5ce268f985cefa5c32e74bab2335f8ace
Author: Rodrigo Sim <[email protected]>
AuthorDate: Sat Nov 11 16:44:03 2023 -0300
stm32f4/stm32f401rc-rs485: add support to userleds
---
boards/arm/stm32/stm32f401rc-rs485/include/board.h | 23 ++-
.../arm/stm32/stm32f401rc-rs485/src/CMakeLists.txt | 4 +
boards/arm/stm32/stm32f401rc-rs485/src/Make.defs | 4 +
.../stm32/stm32f401rc-rs485/src/stm32_bringup.c | 14 ++
.../stm32/stm32f401rc-rs485/src/stm32_userleds.c | 214 +++++++++++++++++++++
.../stm32f401rc-rs485/src/stm32f401rc-rs485.h | 14 +-
6 files changed, 262 insertions(+), 11 deletions(-)
diff --git a/boards/arm/stm32/stm32f401rc-rs485/include/board.h
b/boards/arm/stm32/stm32f401rc-rs485/include/board.h
index 947d49d8bc..da9a00b7ae 100644
--- a/boards/arm/stm32/stm32f401rc-rs485/include/board.h
+++ b/boards/arm/stm32/stm32f401rc-rs485/include/board.h
@@ -36,9 +36,8 @@
/* Clocking *****************************************************************/
-/* The STM32F401RC-RS485 supports both HSE and LSE crystals (X2 and X3).
- * However, as shipped, the X2 and X3 crystals are not populated.
- * Therefore the Nucleo-F401RE will need to run off the 16MHz HSI clock.
+/* The STM32F401RC-RS485 uses an external 32kHz cristal (X2) to enable HSE
+ * clock.
*
* System Clock source : PLL (HSI)
* SYSCLK(Hz) : 84000000 Determined by PLL
@@ -335,22 +334,26 @@ extern "C"
/* LEDs
*
- * The Nucleo F401RE and F411RE boards provide a single user LED, LD2. LD2
- * is the green LED connected to Arduino signal D13 corresponding to MCU I/O
- * PA5 (pin 21) or PB13 (pin 34) depending on the STM32 target.
- *
+ * The STM32F401RC-RS485 boards provide 4 blue user LEDs. LD1, LD2, LD3
+ * and LD4 that are connected to MCU I/O pins PC0, PC1, PC2 and PC3.
* - When the I/O is HIGH value, the LED is on.
* - When the I/O is LOW, the LED is off.
*/
/* LED index values for use with board_userled() */
-#define BOARD_LD2 0
-#define BOARD_NLEDS 1
+#define BOARD_LD1 0
+#define BOARD_LD2 1
+#define BOARD_LD3 2
+#define BOARD_LD4 3
+#define BOARD_NLEDS 4
/* 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
* defined. In that case, the usage by the board port is defined in
diff --git a/boards/arm/stm32/stm32f401rc-rs485/src/CMakeLists.txt
b/boards/arm/stm32/stm32f401rc-rs485/src/CMakeLists.txt
index 9162a3204b..249619b5f7 100644
--- a/boards/arm/stm32/stm32f401rc-rs485/src/CMakeLists.txt
+++ b/boards/arm/stm32/stm32f401rc-rs485/src/CMakeLists.txt
@@ -24,6 +24,10 @@ if(CONFIG_ARCH_LEDS)
list(APPEND SRCS stm32_autoleds.c)
endif()
+if(CONFIG_USERLED)
+ list(APPEND SRCS stm32_userleds.c)
+endif()
+
if(CONFIG_BOARDCTL)
list(APPEND SRCS stm32_appinit.c)
endif()
diff --git a/boards/arm/stm32/stm32f401rc-rs485/src/Make.defs
b/boards/arm/stm32/stm32f401rc-rs485/src/Make.defs
index ba63091126..d7a3d689cf 100644
--- a/boards/arm/stm32/stm32f401rc-rs485/src/Make.defs
+++ b/boards/arm/stm32/stm32f401rc-rs485/src/Make.defs
@@ -27,6 +27,10 @@ ifeq ($(CONFIG_ARCH_LEDS),y)
CSRCS += stm32_autoleds.c
endif
+ifeq ($(CONFIG_USERLED),y)
+CSRCS += stm32_userleds.c
+endif
+
ifeq ($(CONFIG_BOARDCTL),y)
CSRCS += stm32_appinit.c
endif
diff --git a/boards/arm/stm32/stm32f401rc-rs485/src/stm32_bringup.c
b/boards/arm/stm32/stm32f401rc-rs485/src/stm32_bringup.c
index 0baef6aae3..f14e2504e7 100644
--- a/boards/arm/stm32/stm32f401rc-rs485/src/stm32_bringup.c
+++ b/boards/arm/stm32/stm32f401rc-rs485/src/stm32_bringup.c
@@ -35,6 +35,10 @@
#include <arch/board/board.h>
+#ifdef CONFIG_USERLED
+# include <nuttx/leds/userled.h>
+#endif
+
#include "stm32f401rc-rs485.h"
#include <nuttx/board.h>
@@ -61,5 +65,15 @@ int stm32_bringup(void)
{
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;
}
diff --git a/boards/arm/stm32/stm32f401rc-rs485/src/stm32_userleds.c
b/boards/arm/stm32/stm32f401rc-rs485/src/stm32_userleds.c
new file mode 100644
index 0000000000..83e1cabd79
--- /dev/null
+++ b/boards/arm/stm32/stm32f401rc-rs485/src/stm32_userleds.c
@@ -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 */
diff --git a/boards/arm/stm32/stm32f401rc-rs485/src/stm32f401rc-rs485.h
b/boards/arm/stm32/stm32f401rc-rs485/src/stm32f401rc-rs485.h
index d720588b08..1ba37d46c2 100644
--- a/boards/arm/stm32/stm32f401rc-rs485/src/stm32f401rc-rs485.h
+++ b/boards/arm/stm32/stm32f401rc-rs485/src/stm32f401rc-rs485.h
@@ -51,7 +51,19 @@
*/
#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)
/* Buttons