From ece78993b631469c0089af901ba8b5659d577986 Mon Sep 17 00:00:00 2001 From: Rushabh Gala <88271018+rushabhvg@users.noreply.github.com> Date: Tue, 2 Jul 2024 20:07:20 +0530 Subject: [PATCH] risc-v/ox64: Add LED Driver - This PR adds the LED Driver for Ox64 Board (User LEDs and Auto LEDs) - Ox64 LED Driver will be used by the Rust Blinky App for Google Summer of Code - User LED 1 is configured for GPIO 29. Other User LEDs and Auto LEDs shall be configured by the NuttX Dev. - The code is derived from NuttX PinePhone LED Driver --- boards/Kconfig | 1 + .../risc-v/bl808/ox64/configs/nsh/defconfig | 2 + boards/risc-v/bl808/ox64/include/board.h | 22 +- boards/risc-v/bl808/ox64/src/Makefile | 2 +- boards/risc-v/bl808/ox64/src/bl808_appinit.c | 14 + boards/risc-v/bl808/ox64/src/bl808_autoleds.c | 272 ++++++++++++++++++ boards/risc-v/bl808/ox64/src/bl808_userleds.c | 195 +++++++++++++ 7 files changed, 506 insertions(+), 2 deletions(-) create mode 100644 boards/risc-v/bl808/ox64/src/bl808_autoleds.c create mode 100644 boards/risc-v/bl808/ox64/src/bl808_userleds.c diff --git a/boards/Kconfig b/boards/Kconfig index 37f6066502..dc90052624 100644 --- a/boards/Kconfig +++ b/boards/Kconfig @@ -2003,6 +2003,7 @@ config ARCH_BOARD_K230_CANMV config ARCH_BOARD_BL808_OX64 bool "PINE64 Ox64" depends on ARCH_CHIP_BL808 + select ARCH_HAVE_LEDS ---help--- This options selects support for NuttX on PINE64 Ox64 based on Bouffalo Lab BL808 SoC. diff --git a/boards/risc-v/bl808/ox64/configs/nsh/defconfig b/boards/risc-v/bl808/ox64/configs/nsh/defconfig index 49004476b5..a6379f04f1 100644 --- a/boards/risc-v/bl808/ox64/configs/nsh/defconfig +++ b/boards/risc-v/bl808/ox64/configs/nsh/defconfig @@ -94,3 +94,5 @@ CONFIG_UART3_BAUD=2000000 CONFIG_UART3_BITS=7 CONFIG_UART3_SERIAL_CONSOLE=y CONFIG_USEC_PER_TICK=1000 +CONFIG_USERLED=y +CONFIG_USERLED_LOWER=y diff --git a/boards/risc-v/bl808/ox64/include/board.h b/boards/risc-v/bl808/ox64/include/board.h index 59546c4c72..de6e2201f7 100644 --- a/boards/risc-v/bl808/ox64/include/board.h +++ b/boards/risc-v/bl808/ox64/include/board.h @@ -31,6 +31,26 @@ * Pre-processor Definitions ****************************************************************************/ +/* LED definitions **********************************************************/ + +/* LED index values for use with board_userled() */ + +typedef enum +{ + BOARD_LED1 = 0, /* Green LED */ + BOARD_LED2 = 1, /* Red LED */ + BOARD_LED3 = 2, /* Blue LED */ + BOARD_LEDS /* Number of LEDs */ +} led_typedef_enum; + +/* LED bits for use with board_userled_all() */ + +#define BOARD_LED1_BIT (1 << BOARD_LED1) +#define BOARD_LED2_BIT (1 << BOARD_LED2) +#define BOARD_LED3_BIT (1 << BOARD_LED3) + +/* Auto LEDs */ + #define LED_STARTED 0 /* N/A */ #define LED_HEAPALLOCATE 1 /* N/A */ #define LED_IRQSENABLED 2 /* N/A */ @@ -39,7 +59,7 @@ #define LED_SIGNAL 5 /* N/A */ #define LED_ASSERTION 6 /* N/A */ #define LED_PANIC 7 /* N/A */ -#define LED_CPU 8 /* LED */ +#define LED_IDLE 8 /* LED */ /**************************************************************************** * Public Types diff --git a/boards/risc-v/bl808/ox64/src/Makefile b/boards/risc-v/bl808/ox64/src/Makefile index 0131625ea2..3b072df342 100644 --- a/boards/risc-v/bl808/ox64/src/Makefile +++ b/boards/risc-v/bl808/ox64/src/Makefile @@ -22,6 +22,6 @@ include $(TOPDIR)/Make.defs RCSRCS = etc/init.d/rc.sysinit etc/init.d/rcS -CSRCS = bl808_appinit.c +CSRCS = bl808_appinit.c bl808_autoleds.c bl808_userleds.c include $(TOPDIR)/boards/Board.mk diff --git a/boards/risc-v/bl808/ox64/src/bl808_appinit.c b/boards/risc-v/bl808/ox64/src/bl808_appinit.c index d960bc7f4c..36d36a3a55 100644 --- a/boards/risc-v/bl808/ox64/src/bl808_appinit.c +++ b/boards/risc-v/bl808/ox64/src/bl808_appinit.c @@ -35,6 +35,10 @@ #include #include +#ifdef CONFIG_USERLED +#include +#endif + /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ @@ -164,4 +168,14 @@ void board_late_initialize(void) mount(NULL, "/proc", "procfs", 0, NULL); #endif + +#ifdef CONFIG_USERLED + /* Register the LED driver */ + + int ret = userled_lower_initialize("/dev/userleds"); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: userled_lower_initialize() failed: %d\n", ret); + } +#endif } diff --git a/boards/risc-v/bl808/ox64/src/bl808_autoleds.c b/boards/risc-v/bl808/ox64/src/bl808_autoleds.c new file mode 100644 index 0000000000..0751191e6a --- /dev/null +++ b/boards/risc-v/bl808/ox64/src/bl808_autoleds.c @@ -0,0 +1,272 @@ +/**************************************************************************** + * boards/risc-v/bl808/ox64/src/bl808_autoleds.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 "bl808_gpio.h" + +#ifdef CONFIG_ARCH_LEDS + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* LED index */ + +static const uint32_t g_led_map[BOARD_LEDS] = +{ + -1, /* LED1: To be configured */ + -1, /* LED2: To be configured */ + -1 /* LED3: To be configured */ +}; + +static bool g_initialized; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/* Turn on selected led */ + +static void bl808_led_on(led_typedef_enum led_num) +{ + if ((unsigned)led_num < BOARD_LEDS) + { + uint32_t gpio = g_led_map[led_num]; + + if (gpio != (uint32_t)-1) + { + bl808_gpiowrite(gpio, true); + } + } +} + +/* Turn off selected led */ + +static void bl808_led_off(led_typedef_enum led_num) +{ + if ((unsigned)led_num < BOARD_LEDS) + { + uint32_t gpio = g_led_map[led_num]; + + if (gpio != (uint32_t)-1) + { + bl808_gpiowrite(gpio, false); + } + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_autoled_initialize + * + * Description: + * This function is called very early in initialization to perform board- + * specific initialization of LED-related resources. This includes such + * things as, for example, configure GPIO pins to drive the LEDs and also + * putting the LEDs in their correct initial state. + * + * NOTE: In most architectures, board_autoled_initialize() is called from + * board-specific initialization logic. But there are a few architectures + * where this initialization function is still called from common chip + * architecture logic. This interface is not, however, a common board + * interface in any event and, hence, the usage of the name + * board_autoled_initialize is deprecated. + * + * WARNING: This interface name will eventually be removed; do not use it + * in new board ports. New implementations should use the naming + * conventions for "Microprocessor-Specific Interfaces" or the "Board- + * Specific Interfaces" as described above. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void board_autoled_initialize(void) +{ + int i; + + /* Configure the LED GPIO for output. */ + + for (i = 0; i < BOARD_LEDS; i++) + { + uint32_t gpio = g_led_map[i]; + + if (gpio != (uint32_t)-1) + { + int ret = bl808_configgpio(gpio, GPIO_OUTPUT | GPIO_FUNC_SWGPIO); + DEBUGASSERT(ret == OK); + } + } +} + +/**************************************************************************** + * Name: board_autoled_on + * + * Description: + * Set the LED configuration into the ON condition for the state provided + * by the led parameter. This may be one of: + * + * LED_STARTED NuttX has been started + * LED_HEAPALLOCATE Heap has been allocated + * LED_IRQSENABLED Interrupts enabled + * LED_STACKCREATED Idle stack created + * LED_INIRQ In an interrupt + * LED_SIGNAL In a signal handler + * LED_ASSERTION An assertion failed + * LED_PANIC The system has crashed + * LED_IDLE MCU is in sleep mode + * + * Where these values are defined in a board-specific way in the standard + * board.h header file exported by every architecture. + * + * Input Parameters: + * led - Identifies the LED state to put in the ON state (which may or may + * not equate to turning an LED on) + * + * Returned Value: + * None + * + ****************************************************************************/ + +void board_autoled_on(int led) +{ + switch (led) + { + case LED_HEAPALLOCATE: + bl808_led_on(BOARD_LED1); + break; + + case LED_IRQSENABLED: + bl808_led_on(BOARD_LED2); + break; + + case LED_STACKCREATED: + bl808_led_on(BOARD_LED3); + g_initialized = true; + break; + + case LED_INIRQ: + bl808_led_on(BOARD_LED1); + bl808_led_on(BOARD_LED2); + break; + + case LED_SIGNAL: + bl808_led_on(BOARD_LED1); + bl808_led_on(BOARD_LED3); + break; + + case LED_ASSERTION: + bl808_led_on(BOARD_LED2); + bl808_led_on(BOARD_LED3); + break; + + case LED_PANIC: + bl808_led_on(BOARD_LED1); + break; + + case LED_IDLE: + bl808_led_on(BOARD_LED2); + break; + + default: + break; + } +} + +/**************************************************************************** + * Name: board_autoled_off + * + * Description: + * Set the LED configuration into the OFF condition for the state provided + * by the led parameter. This may be one of: + * + * LED_INIRQ Leaving an interrupt + * LED_SIGNAL Leaving a signal handler + * LED_ASSERTION Recovering from an assertion failure + * LED_PANIC The system has crashed (blinking). + * LED_IDLE MCU is not in sleep mode + * + * Where these values are defined in a board-specific way in the standard + * board.h header file exported by every architecture. + * + * Input Parameters: + * led - Identifies the LED state to put in the OFF state (which may or may + * not equate to turning an LED off) + * + * Returned Value: + * None + * + ****************************************************************************/ + +void board_autoled_off(int led) +{ + switch (led) + { + case LED_SIGNAL: + bl808_led_off(BOARD_LED1); + bl808_led_off(BOARD_LED3); + break; + + case LED_INIRQ: + bl808_led_off(BOARD_LED1); + bl808_led_off(BOARD_LED2); + break; + + case LED_ASSERTION: + bl808_led_off(BOARD_LED2); + bl808_led_off(BOARD_LED3); + break; + + case LED_PANIC: + bl808_led_off(BOARD_LED1); + break; + + case LED_IDLE: + bl808_led_off(BOARD_LED2); + break; + + default: + break; + } +} + +#endif /* CONFIG_ARCH_LEDS */ diff --git a/boards/risc-v/bl808/ox64/src/bl808_userleds.c b/boards/risc-v/bl808/ox64/src/bl808_userleds.c new file mode 100644 index 0000000000..3aacc09db6 --- /dev/null +++ b/boards/risc-v/bl808/ox64/src/bl808_userleds.c @@ -0,0 +1,195 @@ +/**************************************************************************** + * boards/risc-v/bl808/ox64/src/bl808_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 + +#include +#include +#include + +#include + +#include +#include + +#include "chip.h" +#include "bl808_gpio.h" + +#ifdef CONFIG_USERLED + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* LED index */ + +static const uint32_t g_led_map[BOARD_LEDS] = +{ + 29, /* LED1: GPIO 29 */ + -1, /* LED2: To be configured */ + -1 /* LED3: To be configured */ +}; + +static const uint32_t g_led_setmap[BOARD_LEDS] = +{ + BOARD_LED1_BIT, + BOARD_LED2_BIT, + BOARD_LED3_BIT +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_userled_initialize + * + * Description: + * This function may called from application-specific logic during its + * to perform board-specific initialization of LED resources. This + * includes such things as, for example, configure GPIO pins to drive the + * LEDs and also putting the LEDs in their correct initial state. + * + * If CONFIG_ARCH_LEDS is defined, then NuttX will control the on-board + * LEDs. If CONFIG_ARCH_LEDS is not defined, then this interfaces may be + * available to control the LEDs directly from user board logic or + * indirectly user applications (via the common LED character driver). + * + * Most boards have only a few LEDs and in those cases all LEDs may be + * used by the NuttX LED logic exclusively and may not be available for + * use by user logic if CONFIG_ARCH_LEDS=y. + * + * NOTE: The LED number is returned. + * + * Input Parameters: + * None + * + * Returned Value: + * Number of LEDs on board + * + ****************************************************************************/ + +uint32_t board_userled_initialize(void) +{ + int i; + + /* Configure the LED GPIO for output. */ + + for (i = 0; i < BOARD_LEDS; i++) + { + uint32_t gpio = g_led_map[i]; + + if (gpio != (uint32_t)-1) + { + int ret = bl808_configgpio(gpio, GPIO_OUTPUT | GPIO_FUNC_SWGPIO); + DEBUGASSERT(ret == OK); + } + } + + return BOARD_LEDS; +} + +/**************************************************************************** + * Name: board_userled + * + * Description: + * This interface may be used by application specific logic to set the + * state of a single LED. Definitions for the led identification are + * provided in the board-specific board.h header file that may be included + * like: + * + * #included + * + * If CONFIG_ARCH_LEDS is defined, then NuttX will control the on-board + * LEDs. If CONFIG_ARCH_LEDS is not defined, then this interfaces may be + * available to control the LEDs directly from user board logic or + * indirectly user applications (via the common LED character driver). + * + * Most boards have only a few LEDs and in those cases all LEDs may be + * used by the NuttX LED logic exclusively and may not be available for + * use by user logic if CONFIG_ARCH_LEDS=y. + * + * Input Parameters: + * led - LED number + * ledon - True if LED should be turned on; False to turn off + * + * Returned Value: + * None + * + ****************************************************************************/ + +void board_userled(int led, bool ledon) +{ + if ((unsigned)led < BOARD_LEDS) + { + uint32_t gpio = g_led_map[led]; + + if (gpio != (uint32_t)-1) + { + bl808_gpiowrite(gpio, ledon); + } + } +} + +/**************************************************************************** + * Name: board_userled_all + * + * Description: + * This interface may be used by application specific logic to set the + * state of all board LED. Definitions for the led set member + * identification is provided in the board-specific board.h header file + * that may be includedlike: + * + * #included + * + * If CONFIG_ARCH_LEDS is defined, then NuttX will control the on-board + * LEDs. If CONFIG_ARCH_LEDS is not defined, then this interfaces may be + * available to control the LEDs directly from user board logic or + * indirectly user applications (via the common LED character driver). + * + * Most boards have only a few LEDs and in those cases all LEDs may be + * used by the NuttX LED logic exclusively and may not be available for + * use by user logic if CONFIG_ARCH_LEDS=y. + * + * Input Parameters: + * ledset - Bitset of LEDs to be turned on and off + * + * Returned Value: + * None + * + ****************************************************************************/ + +void board_userled_all(uint32_t ledset) +{ + int i; + + for (i = 0; i < BOARD_LEDS; i++) + { + bool val = ((ledset & g_led_setmap[i]) != 0); + + board_userled(i, val); + } +} + +#endif /* CONFIG_USERLED */