This is an automated email from the ASF dual-hosted git repository.

xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 2c061c6c18f65a8b791b8dabbcd0f94ca9b4b4f2
Author: leocafonso <[email protected]>
AuthorDate: Wed Sep 30 18:36:00 2026 -0700

    boards/arm/ra8m1: Register the GPT timers and add GPIO support
    
    Register GPT0 (32-bit) as /dev/timer0 and GPT9 (16-bit) as /dev/timer1
    during bring-up.
    
    Register the Arduino Uno shield header's D2-D5 as inputs and D6-D13 as
    outputs through the generic GPIO expander driver, as /dev/gpio0-3 and
    /dev/gpio4-11.
    
    Add the ek-ra8m1:timer-gpio configuration (nsh plus both GPT channels,
    the GPIO support above, and apps/examples/gpio and
    apps/examples/timer_gpio), used to validate the GPT timer driver on
    hardware with an oscilloscope.
    
    Co-Authored-By: Claude Sonnet 5 <[email protected]>
    Assisted-by: Claude:claude-sonnet-5
    Signed-off-by: leocafonso <[email protected]>
---
 .../ra8m1/ek-ra8m1/configs/timer-gpio/defconfig    |  44 +++++
 boards/arm/ra8m1/ek-ra8m1/include/board.h          |  43 +++++
 boards/arm/ra8m1/ek-ra8m1/src/CMakeLists.txt       |   4 +
 boards/arm/ra8m1/ek-ra8m1/src/Makefile             |   4 +
 boards/arm/ra8m1/ek-ra8m1/src/ek_ra8m1.h           |  13 ++
 boards/arm/ra8m1/ek-ra8m1/src/ra8m1_bringup.c      |  32 ++++
 boards/arm/ra8m1/ek-ra8m1/src/ra8m1_gpio.c         | 187 +++++++++++++++++++++
 7 files changed, 327 insertions(+)

diff --git a/boards/arm/ra8m1/ek-ra8m1/configs/timer-gpio/defconfig 
b/boards/arm/ra8m1/ek-ra8m1/configs/timer-gpio/defconfig
new file mode 100644
index 00000000000..390bcbdb887
--- /dev/null
+++ b/boards/arm/ra8m1/ek-ra8m1/configs/timer-gpio/defconfig
@@ -0,0 +1,44 @@
+#
+# 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="arm"
+CONFIG_ARCH_BOARD="ek-ra8m1"
+CONFIG_ARCH_BOARD_EK_RA8M1=y
+CONFIG_ARCH_CHIP="ra8m1"
+CONFIG_ARCH_CHIP_R7FA8M1AHECBD=y
+CONFIG_ARCH_CHIP_RA8M1=y
+CONFIG_ARCH_STACKDUMP=y
+CONFIG_BOARD_LOOPSPERMSEC=43103
+CONFIG_BUILTIN=y
+CONFIG_DEV_GPIO=y
+CONFIG_EXAMPLES_GPIO=y
+CONFIG_EXAMPLES_TIMER_GPIO=y
+CONFIG_EXAMPLES_TIMER_GPIO_INTERVAL=200000
+CONFIG_FS_PROCFS=y
+CONFIG_HAVE_CXX=y
+CONFIG_HAVE_CXXINITIALIZE=y
+CONFIG_INIT_ENTRYPOINT="nsh_main"
+CONFIG_INTELHEX_BINARY=y
+CONFIG_NSH_BUILTIN_APPS=y
+CONFIG_NSH_DISABLE_IFUPDOWN=y
+CONFIG_NSH_FILEIOSIZE=512
+CONFIG_NSH_READLINE=y
+CONFIG_PREALLOC_TIMERS=4
+CONFIG_RAM_SIZE=917504
+CONFIG_RAM_START=0x22000000
+CONFIG_RA_GPT0_GPT=y
+CONFIG_RA_GPT9_GPT=y
+CONFIG_RA_GPT_TIMER=y
+CONFIG_RA_SCI9_UART=y
+CONFIG_RR_INTERVAL=200
+CONFIG_SCHED_WAITPID=y
+CONFIG_SCI9_SERIAL_CONSOLE=y
+CONFIG_START_DAY=28
+CONFIG_START_MONTH=6
+CONFIG_START_YEAR=2013
+CONFIG_SYSTEM_NSH=y
+CONFIG_TASK_NAME_SIZE=32
diff --git a/boards/arm/ra8m1/ek-ra8m1/include/board.h 
b/boards/arm/ra8m1/ek-ra8m1/include/board.h
index 2b4d6eaa1bb..881c3eed67f 100644
--- a/boards/arm/ra8m1/ek-ra8m1/include/board.h
+++ b/boards/arm/ra8m1/ek-ra8m1/include/board.h
@@ -321,6 +321,49 @@
 #define GPIO_SCI9_RX   GPIO_RXD9_MISO9_SCL9_3  /* PA15 */
 #define GPIO_SCI9_TX   GPIO_TXD9_MOSI9_SDA9_3  /* PA14 */
 
+/* Arduino shield header pin selections *************************************/
+
+/* D2-D5 are wired as inputs, D6-D13 as outputs (see
+ * Documentation/platforms/arm/ra8m1/boards/ek-ra8m1 or the schematic,
+ * "EK-RA8M1 Arduino Shield Connection", for the D0-D13/port mapping this is
+ * taken from).  D0/D1 are left alone here since they are SCI9's RXD/TXD
+ * pins, already covered by GPIO_SCI9_RX/GPIO_SCI9_TX above.
+ */
+
+#define GPIO_ARDUINO_D2   (gpio_pinset_t){ PORT9, PIN6,  GPIO_INPUT }  /* P906 
*/
+#define GPIO_ARDUINO_D3   (gpio_pinset_t){ PORT9, PIN7,  GPIO_INPUT }  /* P907 
*/
+#define GPIO_ARDUINO_D4   (gpio_pinset_t){ PORT9, PIN5,  GPIO_INPUT }  /* P905 
*/
+#define GPIO_ARDUINO_D5   (gpio_pinset_t){ PORT6, PIN1,  GPIO_INPUT }  /* P601 
*/
+
+#define GPIO_ARDUINO_D6   (gpio_pinset_t){ PORT6, PIN2,  (GPIO_OUTPUT | 
GPIO_LOW_DRIVE | GPIO_OUTPUT_LOW) }  /* P602 */
+#define GPIO_ARDUINO_D7   (gpio_pinset_t){ PORT9, PIN8,  (GPIO_OUTPUT | 
GPIO_LOW_DRIVE | GPIO_OUTPUT_LOW) }  /* P908 */
+#define GPIO_ARDUINO_D8   (gpio_pinset_t){ PORT9, PIN9,  (GPIO_OUTPUT | 
GPIO_LOW_DRIVE | GPIO_OUTPUT_LOW) }  /* P909 */
+#define GPIO_ARDUINO_D9   (gpio_pinset_t){ PORT6, PIN3,  (GPIO_OUTPUT | 
GPIO_LOW_DRIVE | GPIO_OUTPUT_LOW) }  /* P603 */
+#define GPIO_ARDUINO_D10  (gpio_pinset_t){ PORT4, PIN13, (GPIO_OUTPUT | 
GPIO_LOW_DRIVE | GPIO_OUTPUT_LOW) }  /* P413 */
+#define GPIO_ARDUINO_D11  (gpio_pinset_t){ PORT4, PIN11, (GPIO_OUTPUT | 
GPIO_LOW_DRIVE | GPIO_OUTPUT_LOW) }  /* P411 */
+#define GPIO_ARDUINO_D12  (gpio_pinset_t){ PORT4, PIN10, (GPIO_OUTPUT | 
GPIO_LOW_DRIVE | GPIO_OUTPUT_LOW) }  /* P410 */
+#define GPIO_ARDUINO_D13  (gpio_pinset_t){ PORT4, PIN12, (GPIO_OUTPUT | 
GPIO_LOW_DRIVE | GPIO_OUTPUT_LOW) }  /* P412 */
+
+/* Index values for use with the /dev/gpioN devices ra8m1_gpio.c registers:
+ * inputs first (D2-D5, in header order), then outputs (D6-D13).
+ */
+
+#define BOARD_ARDUINO_D2_GPIO   0
+#define BOARD_ARDUINO_D3_GPIO   1
+#define BOARD_ARDUINO_D4_GPIO   2
+#define BOARD_ARDUINO_D5_GPIO   3
+#define BOARD_NGPIOIN           4
+
+#define BOARD_ARDUINO_D6_GPIO   0
+#define BOARD_ARDUINO_D7_GPIO   1
+#define BOARD_ARDUINO_D8_GPIO   2
+#define BOARD_ARDUINO_D9_GPIO   3
+#define BOARD_ARDUINO_D10_GPIO  4
+#define BOARD_ARDUINO_D11_GPIO  5
+#define BOARD_ARDUINO_D12_GPIO  6
+#define BOARD_ARDUINO_D13_GPIO  7
+#define BOARD_NGPIOOUT          8
+
 /* LED pin selections *******************************************************/
 
 /* The EK-RA8M1 has three user LEDs.  They are driven active high. */
diff --git a/boards/arm/ra8m1/ek-ra8m1/src/CMakeLists.txt 
b/boards/arm/ra8m1/ek-ra8m1/src/CMakeLists.txt
index 0a5cdac40aa..f7b3fecfb38 100644
--- a/boards/arm/ra8m1/ek-ra8m1/src/CMakeLists.txt
+++ b/boards/arm/ra8m1/ek-ra8m1/src/CMakeLists.txt
@@ -26,6 +26,10 @@ else()
   list(APPEND SRCS ra8m1_userleds.c)
 endif()
 
+if(CONFIG_DEV_GPIO)
+  list(APPEND SRCS ra8m1_gpio.c)
+endif()
+
 target_sources(board PRIVATE ${SRCS})
 
 set_property(GLOBAL PROPERTY LD_SCRIPT 
"${NUTTX_BOARD_DIR}/scripts/ek_ra8m1.ld")
diff --git a/boards/arm/ra8m1/ek-ra8m1/src/Makefile 
b/boards/arm/ra8m1/ek-ra8m1/src/Makefile
index 644424ed202..d30a8890cc4 100644
--- a/boards/arm/ra8m1/ek-ra8m1/src/Makefile
+++ b/boards/arm/ra8m1/ek-ra8m1/src/Makefile
@@ -28,4 +28,8 @@ else
 CSRCS += ra8m1_userleds.c
 endif
 
+ifeq ($(CONFIG_DEV_GPIO),y)
+CSRCS += ra8m1_gpio.c
+endif
+
 include $(TOPDIR)/boards/Board.mk
diff --git a/boards/arm/ra8m1/ek-ra8m1/src/ek_ra8m1.h 
b/boards/arm/ra8m1/ek-ra8m1/src/ek_ra8m1.h
index 87d673e17ff..891620fa5e8 100644
--- a/boards/arm/ra8m1/ek-ra8m1/src/ek_ra8m1.h
+++ b/boards/arm/ra8m1/ek-ra8m1/src/ek_ra8m1.h
@@ -51,5 +51,18 @@
 
 int ra8m1_bringup(void);
 
+/****************************************************************************
+ * Name: ra8m1_gpio_initialize
+ *
+ * Description:
+ *   Register the Arduino shield header's D2-D13 with the generic GPIO
+ *   expander driver.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_DEV_GPIO
+int ra8m1_gpio_initialize(void);
+#endif
+
 #endif /* __ASSEMBLY__ */
 #endif /* __BOARDS_ARM_RA8M1_EK_RA8M1_SRC_EK_RA8M1_H */
diff --git a/boards/arm/ra8m1/ek-ra8m1/src/ra8m1_bringup.c 
b/boards/arm/ra8m1/ek-ra8m1/src/ra8m1_bringup.c
index aa56faac05f..882c35b2ef8 100644
--- a/boards/arm/ra8m1/ek-ra8m1/src/ra8m1_bringup.c
+++ b/boards/arm/ra8m1/ek-ra8m1/src/ra8m1_bringup.c
@@ -37,6 +37,10 @@
 
 #include "ek_ra8m1.h"
 
+#ifdef CONFIG_RA_GPT_TIMER
+#  include "ra_gpt.h"
+#endif
+
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
@@ -75,5 +79,33 @@ int ra8m1_bringup(void)
     }
 #endif
 
+#ifdef CONFIG_RA_GPT0_GPT
+  /* GPT0 is a 32-bit timer */
+
+  ret = ra_gpt_timer_initialize("/dev/timer0", 0);
+  if (ret < 0)
+    {
+      syslog(LOG_ERR, "ERROR: GPT0 timer failed: %d\n", ret);
+    }
+#endif
+
+#ifdef CONFIG_RA_GPT9_GPT
+  /* GPT9 is a 16-bit timer */
+
+  ret = ra_gpt_timer_initialize("/dev/timer1", 9);
+  if (ret < 0)
+    {
+      syslog(LOG_ERR, "ERROR: GPT9 timer failed: %d\n", ret);
+    }
+#endif
+
+#ifdef CONFIG_DEV_GPIO
+  ret = ra8m1_gpio_initialize();
+  if (ret < 0)
+    {
+      syslog(LOG_ERR, "ERROR: ra8m1_gpio_initialize() failed: %d\n", ret);
+    }
+#endif
+
   return ret;
 }
diff --git a/boards/arm/ra8m1/ek-ra8m1/src/ra8m1_gpio.c 
b/boards/arm/ra8m1/ek-ra8m1/src/ra8m1_gpio.c
new file mode 100644
index 00000000000..3e46bd0f82d
--- /dev/null
+++ b/boards/arm/ra8m1/ek-ra8m1/src/ra8m1_gpio.c
@@ -0,0 +1,187 @@
+/****************************************************************************
+ * boards/arm/ra8m1/ek-ra8m1/src/ra8m1_gpio.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 <nuttx/config.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <assert.h>
+
+#include <nuttx/ioexpander/gpio.h>
+
+#include <arch/board/board.h>
+
+#include "ra_gpio.h"
+#include "ek_ra8m1.h"
+
+#ifdef CONFIG_DEV_GPIO
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct ra8m1_gpio_dev_s
+{
+  struct gpio_dev_s gpio;
+  uint8_t id;
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int gpin_read(FAR struct gpio_dev_s *dev, FAR bool *value);
+static int gpout_read(FAR struct gpio_dev_s *dev, FAR bool *value);
+static int gpout_write(FAR struct gpio_dev_s *dev, bool value);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct gpio_operations_s g_gpin_ops =
+{
+  .go_read   = gpin_read,
+  .go_write  = NULL,
+  .go_attach = NULL,
+  .go_enable = NULL,
+};
+
+static const struct gpio_operations_s g_gpout_ops =
+{
+  .go_read   = gpout_read,
+  .go_write  = gpout_write,
+  .go_attach = NULL,
+  .go_enable = NULL,
+};
+
+/* The Arduino Uno shield header's D2-D5 (inputs) and D6-D13 (outputs), for
+ * apps that use the generic GPIO expander interface (e.g.
+ * apps/examples/gpio, apps/examples/timer_gpio).  See GPIO_ARDUINO_Dn in
+ * board.h for the pin mapping this comes from.
+ */
+
+static const gpio_pinset_t g_gpioinputs[BOARD_NGPIOIN] =
+{
+  GPIO_ARDUINO_D2, GPIO_ARDUINO_D3, GPIO_ARDUINO_D4, GPIO_ARDUINO_D5
+};
+
+static const gpio_pinset_t g_gpiooutputs[BOARD_NGPIOOUT] =
+{
+  GPIO_ARDUINO_D6, GPIO_ARDUINO_D7, GPIO_ARDUINO_D8, GPIO_ARDUINO_D9,
+  GPIO_ARDUINO_D10, GPIO_ARDUINO_D11, GPIO_ARDUINO_D12, GPIO_ARDUINO_D13
+};
+
+static struct ra8m1_gpio_dev_s g_gpin[BOARD_NGPIOIN];
+static struct ra8m1_gpio_dev_s g_gpout[BOARD_NGPIOOUT];
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int gpin_read(FAR struct gpio_dev_s *dev, FAR bool *value)
+{
+  FAR struct ra8m1_gpio_dev_s *ra8m1gpio =
+    (FAR struct ra8m1_gpio_dev_s *)dev;
+
+  DEBUGASSERT(ra8m1gpio != NULL && value != NULL);
+  DEBUGASSERT(ra8m1gpio->id < BOARD_NGPIOIN);
+
+  *value = ra_gpioread(g_gpioinputs[ra8m1gpio->id]);
+  return OK;
+}
+
+static int gpout_read(FAR struct gpio_dev_s *dev, FAR bool *value)
+{
+  FAR struct ra8m1_gpio_dev_s *ra8m1gpio =
+    (FAR struct ra8m1_gpio_dev_s *)dev;
+
+  DEBUGASSERT(ra8m1gpio != NULL && value != NULL);
+  DEBUGASSERT(ra8m1gpio->id < BOARD_NGPIOOUT);
+
+  *value = ra_gpioread(g_gpiooutputs[ra8m1gpio->id]);
+  return OK;
+}
+
+static int gpout_write(FAR struct gpio_dev_s *dev, bool value)
+{
+  FAR struct ra8m1_gpio_dev_s *ra8m1gpio =
+    (FAR struct ra8m1_gpio_dev_s *)dev;
+
+  DEBUGASSERT(ra8m1gpio != NULL);
+  DEBUGASSERT(ra8m1gpio->id < BOARD_NGPIOOUT);
+
+  ra_gpiowrite(g_gpiooutputs[ra8m1gpio->id], value);
+  return OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: ra8m1_gpio_initialize
+ *
+ * Description:
+ *   Register the Arduino shield header's D2-D5 (inputs) and D6-D13
+ *   (outputs) with the generic GPIO expander driver, as /dev/gpio0-3 and
+ *   /dev/gpio4-11 respectively.
+ *
+ ****************************************************************************/
+
+int ra8m1_gpio_initialize(void)
+{
+  int i;
+  int pincount = 0;
+
+  for (i = 0; i < BOARD_NGPIOIN; i++)
+    {
+      g_gpin[i].gpio.gp_pintype = GPIO_INPUT_PIN;
+      g_gpin[i].gpio.gp_ops     = &g_gpin_ops;
+      g_gpin[i].id              = i;
+      gpio_pin_register(&g_gpin[i].gpio, pincount);
+
+      ra_configgpio(g_gpioinputs[i]);
+
+      pincount++;
+    }
+
+  for (i = 0; i < BOARD_NGPIOOUT; i++)
+    {
+      g_gpout[i].gpio.gp_pintype = GPIO_OUTPUT_PIN;
+      g_gpout[i].gpio.gp_ops     = &g_gpout_ops;
+      g_gpout[i].id              = i;
+      gpio_pin_register(&g_gpout[i].gpio, pincount);
+
+      ra_gpiowrite(g_gpiooutputs[i], false);
+      ra_configgpio(g_gpiooutputs[i]);
+
+      pincount++;
+    }
+
+  return OK;
+}
+
+#endif /* CONFIG_DEV_GPIO */

Reply via email to