summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRbb666 <[email protected]>2026-07-31 15:23:24 +0800
committerRbb666 <[email protected]>2026-08-12 12:54:50 +0800
commitabce28f15cc868f72d0d1f2bfc7e46343869e6d6 (patch)
treea0a3515b469994332db81b65b7497a4ffe5f2d67
parent655aea948e8d1c5e77cd2a9b85cd45bf864df72d (diff)
feat(renesas): add RA8P1 GPIO and external IRQ DM drivers
Add M85 device-tree GPIO and external-interrupt controllers, IRQ20 FSP integration, built-in DTB support, and BSP usage documentation.
-rw-r--r--bsp/renesas/libraries/HAL_Drivers/drivers/SConscript7
-rw-r--r--bsp/renesas/libraries/HAL_Drivers/drivers/dm/SConscript23
-rw-r--r--bsp/renesas/libraries/HAL_Drivers/drivers/dm/builtin_fdt_gcc.S17
-rw-r--r--bsp/renesas/libraries/HAL_Drivers/drivers/dm/drv_external_irq.c581
-rw-r--r--bsp/renesas/libraries/HAL_Drivers/drivers/dm/drv_external_irq.h25
-rw-r--r--bsp/renesas/libraries/HAL_Drivers/drivers/dm/drv_gpio.c554
-rw-r--r--bsp/renesas/libraries/HAL_Drivers/drv_common.c30
-rw-r--r--bsp/renesas/ra8p1-titan-board/README.md10
-rw-r--r--bsp/renesas/ra8p1-titan-board/README_zh.md10
-rw-r--r--bsp/renesas/ra8p1-titan-board/m85/.settings/standalone.prefs2
-rw-r--r--bsp/renesas/ra8p1-titan-board/m85/Kconfig10
-rw-r--r--bsp/renesas/ra8p1-titan-board/m85/SConstruct25
-rw-r--r--bsp/renesas/ra8p1-titan-board/m85/board/dts/ra8p1-titan-m85.dts74
-rw-r--r--bsp/renesas/ra8p1-titan-board/m85/configuration.xml23
-rw-r--r--bsp/renesas/ra8p1-titan-board/m85/ra/fsp/inc/api/r_external_irq_api.h154
-rw-r--r--bsp/renesas/ra8p1-titan-board/m85/ra/fsp/inc/instances/r_icu.h94
-rw-r--r--bsp/renesas/ra8p1-titan-board/m85/ra/fsp/src/r_icu/r_icu.c439
-rw-r--r--bsp/renesas/ra8p1-titan-board/m85/ra_cfg/fsp_cfg/bsp/bsp_mcu_family_cfg.h2
-rw-r--r--bsp/renesas/ra8p1-titan-board/m85/ra_cfg/fsp_cfg/r_icu_cfg.h13
-rw-r--r--bsp/renesas/ra8p1-titan-board/m85/ra_gen/common_data.c36
-rw-r--r--bsp/renesas/ra8p1-titan-board/m85/ra_gen/common_data.h12
-rw-r--r--bsp/renesas/ra8p1-titan-board/m85/ra_gen/pin_data.c7
-rw-r--r--bsp/renesas/ra8p1-titan-board/m85/ra_gen/vector_data.c2
-rw-r--r--bsp/renesas/ra8p1-titan-board/m85/ra_gen/vector_data.h7
-rw-r--r--bsp/renesas/ra8p1-titan-board/m85/rtconfig.py2
-rw-r--r--bsp/renesas/ra8p1-titan-board/m85/script/fsp.ld120
-rw-r--r--bsp/renesas/ra8p1-titan-board/m85/src/hal_entry.c9
27 files changed, 2219 insertions, 69 deletions
diff --git a/bsp/renesas/libraries/HAL_Drivers/drivers/SConscript b/bsp/renesas/libraries/HAL_Drivers/drivers/SConscript
index 9a7a6b62a6..b7e96ae967 100644
--- a/bsp/renesas/libraries/HAL_Drivers/drivers/SConscript
+++ b/bsp/renesas/libraries/HAL_Drivers/drivers/SConscript
@@ -3,6 +3,7 @@ Import('rtconfig')
from building import *
cwd = GetCurrentDir()
+group = []
# add the general drivers.
src = []
@@ -14,7 +15,9 @@ if GetDepend(['BSP_USING_UART']):
print("\nThe current project does not support serial-v1\n")
Return('group')
-if GetDepend(['BSP_USING_GPIO']):
+if GetDepend(['RT_USING_DM']):
+ group += SConscript(os.path.join('dm', 'SConscript'))
+elif GetDepend(['BSP_USING_GPIO']):
src += ['drv_gpio.c']
if GetDepend(['BSP_USING_WDT']):
@@ -65,6 +68,6 @@ if GetDepend(['BSP_USING_RS485']):
path = [cwd]
path += [cwd + '/config']
-group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path)
+group += DefineGroup('Drivers', src, depend = [''], CPPPATH = path)
Return('group')
diff --git a/bsp/renesas/libraries/HAL_Drivers/drivers/dm/SConscript b/bsp/renesas/libraries/HAL_Drivers/drivers/dm/SConscript
new file mode 100644
index 0000000000..8982904c2e
--- /dev/null
+++ b/bsp/renesas/libraries/HAL_Drivers/drivers/dm/SConscript
@@ -0,0 +1,23 @@
+Import('RTT_ROOT')
+Import('rtconfig')
+
+from building import *
+import os
+
+cwd = GetCurrentDir()
+parent = os.path.dirname(cwd)
+src = ['drv_external_irq.c']
+
+if GetDepend(['BSP_USING_GPIO']):
+ src += ['drv_gpio.c']
+path = [
+ cwd,
+ parent,
+ os.path.join(parent, 'config'),
+ os.path.join(RTT_ROOT, 'components', 'drivers', 'pin'),
+]
+
+group = DefineGroup('Renesas DM Drivers', src,
+ depend = ['RT_USING_DM'], CPPPATH = path)
+
+Return('group')
diff --git a/bsp/renesas/libraries/HAL_Drivers/drivers/dm/builtin_fdt_gcc.S b/bsp/renesas/libraries/HAL_Drivers/drivers/dm/builtin_fdt_gcc.S
new file mode 100644
index 0000000000..99cb997180
--- /dev/null
+++ b/bsp/renesas/libraries/HAL_Drivers/drivers/dm/builtin_fdt_gcc.S
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2006-2026, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <rtconfig.h>
+
+ .section .rodata.dtb, "a", %progbits
+ .balign 8
+ .global rt_hw_builtin_fdt
+ .type rt_hw_builtin_fdt, %object
+rt_hw_builtin_fdt:
+#ifdef RT_BUILTIN_FDT_PATH
+ .incbin RT_BUILTIN_FDT_PATH
+#endif
+ .size rt_hw_builtin_fdt, . - rt_hw_builtin_fdt
diff --git a/bsp/renesas/libraries/HAL_Drivers/drivers/dm/drv_external_irq.c b/bsp/renesas/libraries/HAL_Drivers/drivers/dm/drv_external_irq.c
new file mode 100644
index 0000000000..42700231fc
--- /dev/null
+++ b/bsp/renesas/libraries/HAL_Drivers/drivers/dm/drv_external_irq.c
@@ -0,0 +1,581 @@
+/*
+ * Copyright (c) 2006-2026, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2026-07-31 RTT the first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#define DBG_TAG "drv.ra.extirq"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+#include <drivers/core/dm.h>
+#include <drivers/ofw.h>
+#include <drivers/ofw_irq.h>
+#include <drivers/pic.h>
+#include <drivers/platform.h>
+
+#include <hal_data.h>
+
+#include "drv_external_irq.h"
+
+#ifdef R_ICU_H
+#define RA_EXTERNAL_IRQ_MAX_CHANNELS 32
+
+struct ra_external_irq
+{
+ struct rt_pic parent;
+ const external_irq_instance_t *fsp;
+ external_irq_cfg_t cfg;
+ int irq;
+ rt_uint8_t channel;
+ rt_uint8_t owner_port;
+ rt_uint8_t owner_pin;
+ rt_bool_t acquired;
+ rt_bool_t opened;
+ rt_bool_t enabled;
+};
+
+static struct ra_external_irq *ra_external_irqs[RA_EXTERNAL_IRQ_MAX_CHANNELS];
+
+#define RA_EXTERNAL_IRQ_INSTANCE(_channel) \
+ [_channel] = &g_external_irq##_channel
+
+static const external_irq_instance_t * const
+ ra_external_irq_instances[RA_EXTERNAL_IRQ_MAX_CHANNELS] = {
+#if defined(VECTOR_NUMBER_ICU_IRQ0) || defined(VECTOR_NUMBER_IRQ0)
+ RA_EXTERNAL_IRQ_INSTANCE(0),
+#endif
+#if defined(VECTOR_NUMBER_ICU_IRQ1) || defined(VECTOR_NUMBER_IRQ1)
+ RA_EXTERNAL_IRQ_INSTANCE(1),
+#endif
+#if defined(VECTOR_NUMBER_ICU_IRQ2) || defined(VECTOR_NUMBER_IRQ2)
+ RA_EXTERNAL_IRQ_INSTANCE(2),
+#endif
+#if defined(VECTOR_NUMBER_ICU_IRQ3) || defined(VECTOR_NUMBER_IRQ3)
+ RA_EXTERNAL_IRQ_INSTANCE(3),
+#endif
+#if defined(VECTOR_NUMBER_ICU_IRQ4) || defined(VECTOR_NUMBER_IRQ4)
+ RA_EXTERNAL_IRQ_INSTANCE(4),
+#endif
+#if defined(VECTOR_NUMBER_ICU_IRQ5) || defined(VECTOR_NUMBER_IRQ5)
+ RA_EXTERNAL_IRQ_INSTANCE(5),
+#endif
+#if defined(VECTOR_NUMBER_ICU_IRQ6) || defined(VECTOR_NUMBER_IRQ6)
+ RA_EXTERNAL_IRQ_INSTANCE(6),
+#endif
+#if defined(VECTOR_NUMBER_ICU_IRQ7) || defined(VECTOR_NUMBER_IRQ7)
+ RA_EXTERNAL_IRQ_INSTANCE(7),
+#endif
+#if defined(VECTOR_NUMBER_ICU_IRQ8) || defined(VECTOR_NUMBER_IRQ8)
+ RA_EXTERNAL_IRQ_INSTANCE(8),
+#endif
+#if defined(VECTOR_NUMBER_ICU_IRQ9) || defined(VECTOR_NUMBER_IRQ9)
+ RA_EXTERNAL_IRQ_INSTANCE(9),
+#endif
+#if defined(VECTOR_NUMBER_ICU_IRQ10) || defined(VECTOR_NUMBER_IRQ10)
+ RA_EXTERNAL_IRQ_INSTANCE(10),
+#endif
+#if defined(VECTOR_NUMBER_ICU_IRQ11) || defined(VECTOR_NUMBER_IRQ11)
+ RA_EXTERNAL_IRQ_INSTANCE(11),
+#endif
+#if defined(VECTOR_NUMBER_ICU_IRQ12) || defined(VECTOR_NUMBER_IRQ12)
+ RA_EXTERNAL_IRQ_INSTANCE(12),
+#endif
+#if defined(VECTOR_NUMBER_ICU_IRQ13) || defined(VECTOR_NUMBER_IRQ13)
+ RA_EXTERNAL_IRQ_INSTANCE(13),
+#endif
+#if defined(VECTOR_NUMBER_ICU_IRQ14) || defined(VECTOR_NUMBER_IRQ14)
+ RA_EXTERNAL_IRQ_INSTANCE(14),
+#endif
+#if defined(VECTOR_NUMBER_ICU_IRQ15) || defined(VECTOR_NUMBER_IRQ15)
+ RA_EXTERNAL_IRQ_INSTANCE(15),
+#endif
+#if defined(VECTOR_NUMBER_ICU_IRQ16) || defined(VECTOR_NUMBER_IRQ16)
+ RA_EXTERNAL_IRQ_INSTANCE(16),
+#endif
+#if defined(VECTOR_NUMBER_ICU_IRQ17) || defined(VECTOR_NUMBER_IRQ17)
+ RA_EXTERNAL_IRQ_INSTANCE(17),
+#endif
+#if defined(VECTOR_NUMBER_ICU_IRQ18) || defined(VECTOR_NUMBER_IRQ18)
+ RA_EXTERNAL_IRQ_INSTANCE(18),
+#endif
+#if defined(VECTOR_NUMBER_ICU_IRQ19) || defined(VECTOR_NUMBER_IRQ19)
+ RA_EXTERNAL_IRQ_INSTANCE(19),
+#endif
+#if defined(VECTOR_NUMBER_ICU_IRQ20) || defined(VECTOR_NUMBER_IRQ20)
+ RA_EXTERNAL_IRQ_INSTANCE(20),
+#endif
+#if defined(VECTOR_NUMBER_ICU_IRQ21) || defined(VECTOR_NUMBER_IRQ21)
+ RA_EXTERNAL_IRQ_INSTANCE(21),
+#endif
+#if defined(VECTOR_NUMBER_ICU_IRQ22) || defined(VECTOR_NUMBER_IRQ22)
+ RA_EXTERNAL_IRQ_INSTANCE(22),
+#endif
+#if defined(VECTOR_NUMBER_ICU_IRQ23) || defined(VECTOR_NUMBER_IRQ23)
+ RA_EXTERNAL_IRQ_INSTANCE(23),
+#endif
+#if defined(VECTOR_NUMBER_ICU_IRQ24) || defined(VECTOR_NUMBER_IRQ24)
+ RA_EXTERNAL_IRQ_INSTANCE(24),
+#endif
+#if defined(VECTOR_NUMBER_ICU_IRQ25) || defined(VECTOR_NUMBER_IRQ25)
+ RA_EXTERNAL_IRQ_INSTANCE(25),
+#endif
+#if defined(VECTOR_NUMBER_ICU_IRQ26) || defined(VECTOR_NUMBER_IRQ26)
+ RA_EXTERNAL_IRQ_INSTANCE(26),
+#endif
+#if defined(VECTOR_NUMBER_ICU_IRQ27) || defined(VECTOR_NUMBER_IRQ27)
+ RA_EXTERNAL_IRQ_INSTANCE(27),
+#endif
+#if defined(VECTOR_NUMBER_ICU_IRQ28) || defined(VECTOR_NUMBER_IRQ28)
+ RA_EXTERNAL_IRQ_INSTANCE(28),
+#endif
+ };
+
+#undef RA_EXTERNAL_IRQ_INSTANCE
+
+static const external_irq_instance_t *ra_external_irq_instance_get(
+ rt_uint32_t channel)
+{
+ if (channel < RT_ARRAY_SIZE(ra_external_irq_instances))
+ {
+ return ra_external_irq_instances[channel];
+ }
+
+ return RT_NULL;
+}
+
+static rt_err_t ra_external_irq_mode_to_fsp(rt_uint8_t mode,
+ external_irq_trigger_t *trigger)
+{
+ switch (mode)
+ {
+ case PIN_IRQ_MODE_RISING:
+ *trigger = EXTERNAL_IRQ_TRIG_RISING;
+ break;
+
+ case PIN_IRQ_MODE_FALLING:
+ *trigger = EXTERNAL_IRQ_TRIG_FALLING;
+ break;
+
+ case PIN_IRQ_MODE_RISING_FALLING:
+ *trigger = EXTERNAL_IRQ_TRIG_BOTH_EDGE;
+ break;
+
+ case PIN_IRQ_MODE_LOW_LEVEL:
+ *trigger = EXTERNAL_IRQ_TRIG_LEVEL_LOW;
+ break;
+
+ case PIN_IRQ_MODE_HIGH_LEVEL:
+ *trigger = EXTERNAL_IRQ_TRIG_LEVEL_HIGH;
+ break;
+
+ default:
+ return -RT_EINVAL;
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t ra_external_irq_trigger_from_ofw(const char *name,
+ external_irq_trigger_t *trigger)
+{
+ if (!rt_strcmp(name, "falling"))
+ {
+ *trigger = EXTERNAL_IRQ_TRIG_FALLING;
+ }
+ else if (!rt_strcmp(name, "rising"))
+ {
+ *trigger = EXTERNAL_IRQ_TRIG_RISING;
+ }
+ else if (!rt_strcmp(name, "both-edges"))
+ {
+ *trigger = EXTERNAL_IRQ_TRIG_BOTH_EDGE;
+ }
+ else if (!rt_strcmp(name, "low-level"))
+ {
+ *trigger = EXTERNAL_IRQ_TRIG_LEVEL_LOW;
+ }
+ else
+ {
+ return -RT_EINVAL;
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t ra_external_irq_clock_div_from_ofw(rt_uint32_t value,
+ external_irq_clock_source_div_t *clock_div)
+{
+ switch (value)
+ {
+ case 1:
+ *clock_div = EXTERNAL_IRQ_CLOCK_SOURCE_DIV_1;
+ break;
+
+ case 8:
+ *clock_div = EXTERNAL_IRQ_CLOCK_SOURCE_DIV_8;
+ break;
+
+ case 32:
+ *clock_div = EXTERNAL_IRQ_CLOCK_SOURCE_DIV_32;
+ break;
+
+ case 64:
+ *clock_div = EXTERNAL_IRQ_CLOCK_SOURCE_DIV_64;
+ break;
+
+ default:
+ return -RT_EINVAL;
+ }
+
+ return RT_EOK;
+}
+
+static rt_bool_t ra_external_irq_owner_is(struct ra_external_irq *external_irq,
+ rt_uint8_t port, rt_uint8_t pin)
+{
+ return external_irq->acquired && external_irq->owner_port == port &&
+ external_irq->owner_pin == pin;
+}
+
+struct ra_external_irq *ra_external_irq_get(struct rt_ofw_node *np)
+{
+ if (!np)
+ {
+ return RT_NULL;
+ }
+
+ if (!rt_ofw_data(np))
+ {
+ rt_platform_ofw_request(np);
+ }
+
+ return rt_ofw_data(np);
+}
+
+int ra_external_irq_acquire(struct ra_external_irq *external_irq,
+ rt_uint8_t port, rt_uint8_t pin, rt_uint8_t mode)
+{
+ rt_err_t err;
+ fsp_err_t fsp_err;
+ external_irq_trigger_t trigger;
+
+ if (!external_irq ||
+ (err = ra_external_irq_mode_to_fsp(mode, &trigger)))
+ {
+ return external_irq ? err : -RT_EINVAL;
+ }
+
+ if (external_irq->acquired)
+ {
+ if (!ra_external_irq_owner_is(external_irq, port, pin) ||
+ external_irq->cfg.trigger != trigger)
+ {
+ return -RT_EBUSY;
+ }
+
+ return external_irq->irq;
+ }
+
+ external_irq->cfg = *external_irq->fsp->p_cfg;
+ external_irq->cfg.trigger = trigger;
+ external_irq->cfg.p_callback = irq_callback;
+ external_irq->cfg.p_context = external_irq;
+
+ fsp_err = external_irq->fsp->p_api->open(external_irq->fsp->p_ctrl,
+ &external_irq->cfg);
+ if (fsp_err != FSP_SUCCESS)
+ {
+ LOG_E("IRQ%u open failed: %d", external_irq->channel, fsp_err);
+ return -RT_EIO;
+ }
+
+ external_irq->owner_port = port;
+ external_irq->owner_pin = pin;
+ external_irq->opened = RT_TRUE;
+ external_irq->acquired = RT_TRUE;
+
+ return external_irq->irq;
+}
+
+rt_err_t ra_external_irq_enable(struct ra_external_irq *external_irq,
+ rt_uint8_t port, rt_uint8_t pin)
+{
+ fsp_err_t fsp_err;
+
+ if (!external_irq || !ra_external_irq_owner_is(external_irq, port, pin) ||
+ !external_irq->opened)
+ {
+ return -RT_EINVAL;
+ }
+
+ if (external_irq->enabled)
+ {
+ return RT_EOK;
+ }
+
+ fsp_err = external_irq->fsp->p_api->enable(external_irq->fsp->p_ctrl);
+ if (fsp_err != FSP_SUCCESS)
+ {
+ LOG_E("IRQ%u enable failed: %d", external_irq->channel, fsp_err);
+ return -RT_EIO;
+ }
+
+ external_irq->enabled = RT_TRUE;
+
+ return RT_EOK;
+}
+
+rt_err_t ra_external_irq_disable(struct ra_external_irq *external_irq,
+ rt_uint8_t port, rt_uint8_t pin)
+{
+ fsp_err_t fsp_err;
+
+ if (!external_irq || !ra_external_irq_owner_is(external_irq, port, pin))
+ {
+ return -RT_EINVAL;
+ }
+
+ if (!external_irq->enabled)
+ {
+ return RT_EOK;
+ }
+
+ fsp_err = external_irq->fsp->p_api->disable(external_irq->fsp->p_ctrl);
+ if (fsp_err != FSP_SUCCESS)
+ {
+ LOG_E("IRQ%u disable failed: %d", external_irq->channel, fsp_err);
+ return -RT_EIO;
+ }
+
+ external_irq->enabled = RT_FALSE;
+
+ return RT_EOK;
+}
+
+rt_err_t ra_external_irq_release(struct ra_external_irq *external_irq,
+ rt_uint8_t port, rt_uint8_t pin)
+{
+ rt_err_t err;
+ fsp_err_t fsp_err;
+
+ if (!external_irq || !ra_external_irq_owner_is(external_irq, port, pin))
+ {
+ return -RT_EINVAL;
+ }
+
+ if ((err = ra_external_irq_disable(external_irq, port, pin)))
+ {
+ return err;
+ }
+
+ if (external_irq->opened)
+ {
+ fsp_err = external_irq->fsp->p_api->close(external_irq->fsp->p_ctrl);
+ if (fsp_err != FSP_SUCCESS)
+ {
+ LOG_E("IRQ%u close failed: %d", external_irq->channel, fsp_err);
+ return -RT_EIO;
+ }
+ }
+
+ external_irq->opened = RT_FALSE;
+ external_irq->acquired = RT_FALSE;
+ external_irq->owner_port = 0;
+ external_irq->owner_pin = 0;
+
+ return RT_EOK;
+}
+
+void irq_callback(external_irq_callback_args_t *args)
+{
+ struct ra_external_irq *external_irq;
+ struct rt_pic_irq *pirq;
+
+ if (!args || args->channel >= RA_EXTERNAL_IRQ_MAX_CHANNELS ||
+ !(external_irq = ra_external_irqs[args->channel]) ||
+ !external_irq->enabled)
+ {
+ return;
+ }
+
+ pirq = rt_pic_find_irq(&external_irq->parent, 0);
+ if (pirq->irq >= 0)
+ {
+ rt_interrupt_enter();
+ rt_pic_handle_isr(pirq);
+ rt_interrupt_leave();
+ }
+}
+
+static const struct rt_pic_ops ra_external_irq_pic_ops = {
+ .name = "RA-External-IRQ",
+};
+
+static rt_err_t ra_external_irq_probe(struct rt_platform_device *pdev)
+{
+ rt_err_t err;
+ const char *trigger_name;
+ rt_uint32_t channel, clock_div;
+ struct rt_ofw_cell_args irq_args = { 0 };
+ struct rt_device *dev = &pdev->parent;
+ struct ra_external_irq *external_irq;
+ external_irq_trigger_t trigger;
+ external_irq_clock_source_div_t clock_source_div;
+
+ if ((err = rt_ofw_prop_read_u32(dev->ofw_node, "channel", &channel)))
+ {
+ return err;
+ }
+ if (channel >= RA_EXTERNAL_IRQ_MAX_CHANNELS)
+ {
+ return -RT_EINVAL;
+ }
+
+ external_irq = rt_calloc(1, sizeof(*external_irq));
+ if (!external_irq)
+ {
+ return -RT_ENOMEM;
+ }
+
+ external_irq->fsp = ra_external_irq_instance_get(channel);
+ if (!external_irq->fsp || external_irq->fsp->p_cfg->channel != channel ||
+ external_irq->fsp->p_cfg->p_callback != irq_callback)
+ {
+ err = -RT_EINVAL;
+ goto _fail;
+ }
+
+ if ((err = rt_ofw_prop_read_string(dev->ofw_node, "renesas,trigger",
+ &trigger_name)) ||
+ (err = ra_external_irq_trigger_from_ofw(trigger_name, &trigger)) ||
+ trigger != external_irq->fsp->p_cfg->trigger)
+ {
+ err = err ? err : -RT_EINVAL;
+ goto _fail;
+ }
+
+ clock_div = 1;
+ rt_ofw_prop_read_u32(dev->ofw_node, "renesas,sample-clock-div",
+ &clock_div);
+ if ((err = ra_external_irq_clock_div_from_ofw(clock_div,
+ &clock_source_div)) ||
+ clock_source_div != external_irq->fsp->p_cfg->clock_source_div ||
+ rt_ofw_prop_read_bool(dev->ofw_node, "renesas,digital-filtering") !=
+ external_irq->fsp->p_cfg->filter_enable)
+ {
+ err = err ? err : -RT_EINVAL;
+ goto _fail;
+ }
+
+ if ((err = rt_ofw_parse_irq_cells(dev->ofw_node, 0, &irq_args)))
+ {
+ goto _fail;
+ }
+ if (irq_args.args_count != 2 ||
+ irq_args.args[0] != (rt_uint32_t)external_irq->fsp->p_cfg->irq ||
+ irq_args.args[1] != external_irq->fsp->p_cfg->ipl)
+ {
+ err = -RT_EINVAL;
+ goto _put_irq_node;
+ }
+
+ external_irq->channel = channel;
+ external_irq->parent.ops = &ra_external_irq_pic_ops;
+ external_irq->parent.priv_data = external_irq;
+ if ((err = rt_pic_linear_irq(&external_irq->parent, 1)))
+ {
+ goto _put_irq_node;
+ }
+
+ external_irq->irq = rt_pic_config_irq(&external_irq->parent, 0, channel);
+ if (external_irq->irq < 0)
+ {
+ err = external_irq->irq;
+ rt_pic_cancel_irq(&external_irq->parent);
+ goto _put_irq_node;
+ }
+
+ rt_pic_user_extends(&external_irq->parent);
+ ra_external_irqs[channel] = external_irq;
+ rt_dm_dev_bind_fwdata(dev, RT_NULL, external_irq);
+ pdev->priv = external_irq;
+ rt_ofw_node_put(irq_args.data);
+
+ return RT_EOK;
+
+_put_irq_node:
+ rt_ofw_node_put(irq_args.data);
+_fail:
+ rt_free(external_irq);
+
+ return err;
+}
+
+static const struct rt_ofw_node_id ra_external_irq_ofw_ids[] = {
+ { .compatible = "renesas,ra-external-interrupt" },
+ { /* sentinel */ }
+};
+
+static struct rt_platform_driver ra_external_irq_driver = {
+ .name = "ra-external-interrupt",
+ .ids = ra_external_irq_ofw_ids,
+ .probe = ra_external_irq_probe,
+};
+RT_PLATFORM_DRIVER_EXPORT(ra_external_irq_driver);
+#else
+struct ra_external_irq *ra_external_irq_get(struct rt_ofw_node *np)
+{
+ RT_UNUSED(np);
+
+ return RT_NULL;
+}
+
+int ra_external_irq_acquire(struct ra_external_irq *external_irq,
+ rt_uint8_t port, rt_uint8_t pin, rt_uint8_t mode)
+{
+ RT_UNUSED(external_irq);
+ RT_UNUSED(port);
+ RT_UNUSED(pin);
+ RT_UNUSED(mode);
+
+ return -RT_ENOSYS;
+}
+
+rt_err_t ra_external_irq_enable(struct ra_external_irq *external_irq,
+ rt_uint8_t port, rt_uint8_t pin)
+{
+ RT_UNUSED(external_irq);
+ RT_UNUSED(port);
+ RT_UNUSED(pin);
+
+ return -RT_ENOSYS;
+}
+
+rt_err_t ra_external_irq_disable(struct ra_external_irq *external_irq,
+ rt_uint8_t port, rt_uint8_t pin)
+{
+ RT_UNUSED(external_irq);
+ RT_UNUSED(port);
+ RT_UNUSED(pin);
+
+ return -RT_ENOSYS;
+}
+
+rt_err_t ra_external_irq_release(struct ra_external_irq *external_irq,
+ rt_uint8_t port, rt_uint8_t pin)
+{
+ RT_UNUSED(external_irq);
+ RT_UNUSED(port);
+ RT_UNUSED(pin);
+
+ return -RT_ENOSYS;
+}
+#endif /* R_ICU_H */
diff --git a/bsp/renesas/libraries/HAL_Drivers/drivers/dm/drv_external_irq.h b/bsp/renesas/libraries/HAL_Drivers/drivers/dm/drv_external_irq.h
new file mode 100644
index 0000000000..d32350e92e
--- /dev/null
+++ b/bsp/renesas/libraries/HAL_Drivers/drivers/dm/drv_external_irq.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2006-2026, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef __DRV_EXTERNAL_IRQ_H__
+#define __DRV_EXTERNAL_IRQ_H__
+
+#include <rtdevice.h>
+#include <drivers/ofw.h>
+
+struct ra_external_irq;
+
+struct ra_external_irq *ra_external_irq_get(struct rt_ofw_node *np);
+int ra_external_irq_acquire(struct ra_external_irq *external_irq,
+ rt_uint8_t port, rt_uint8_t pin, rt_uint8_t mode);
+rt_err_t ra_external_irq_enable(struct ra_external_irq *external_irq,
+ rt_uint8_t port, rt_uint8_t pin);
+rt_err_t ra_external_irq_disable(struct ra_external_irq *external_irq,
+ rt_uint8_t port, rt_uint8_t pin);
+rt_err_t ra_external_irq_release(struct ra_external_irq *external_irq,
+ rt_uint8_t port, rt_uint8_t pin);
+
+#endif /* __DRV_EXTERNAL_IRQ_H__ */
diff --git a/bsp/renesas/libraries/HAL_Drivers/drivers/dm/drv_gpio.c b/bsp/renesas/libraries/HAL_Drivers/drivers/dm/drv_gpio.c
new file mode 100644
index 0000000000..3d56331f2a
--- /dev/null
+++ b/bsp/renesas/libraries/HAL_Drivers/drivers/dm/drv_gpio.c
@@ -0,0 +1,554 @@
+/*
+ * Copyright (c) 2006-2026, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2026-07-31 RTT the first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#define DBG_TAG "drv.ra.gpio"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+#include <drivers/core/dm.h>
+#include <drivers/ofw.h>
+#include <drivers/platform.h>
+#include <drivers/pic.h>
+#include <dt-bindings/pin/pin.h>
+
+#include <hal_data.h>
+
+#include "dev_pin_dm.h"
+#include "drv_external_irq.h"
+
+#define RA_GPIO_PIN_NR 16
+
+struct ra_gpio_irq
+{
+ struct ra_external_irq *external_irq;
+ int irq;
+ rt_uint8_t mode;
+ rt_bool_t acquired;
+ rt_bool_t pic_attached;
+ rt_bool_t enabled;
+ void (*handler)(void *args);
+ void *args;
+};
+
+struct ra_gpio
+{
+ struct rt_device_pin parent;
+ rt_uint8_t port;
+ rt_uint8_t ngpios;
+ rt_uint32_t pin_cfg[RA_GPIO_PIN_NR];
+ struct ra_gpio_irq irqs[RA_GPIO_PIN_NR];
+};
+
+static struct ra_gpio *device_to_ra_gpio(struct rt_device *device)
+{
+ struct rt_device_pin *pin = rt_container_of(device,
+ struct rt_device_pin, parent);
+
+ return rt_container_of(pin, struct ra_gpio, parent);
+}
+
+static bsp_io_port_pin_t ra_gpio_fsp_pin(struct ra_gpio *gpio, rt_base_t pin)
+{
+ return (bsp_io_port_pin_t)(((rt_uint32_t)gpio->port << 8) | pin);
+}
+
+static rt_bool_t ra_gpio_pin_is_valid(struct ra_gpio *gpio, rt_base_t pin)
+{
+ return pin >= 0 && pin < gpio->ngpios;
+}
+
+static rt_uint32_t ra_gpio_board_pin_cfg(struct ra_gpio *gpio, rt_base_t pin)
+{
+ bsp_io_port_pin_t fsp_pin = ra_gpio_fsp_pin(gpio, pin);
+
+ for (rt_uint32_t i = 0; i < g_bsp_pin_cfg.number_of_pins; ++i)
+ {
+ if (g_bsp_pin_cfg.p_pin_cfg_data[i].pin == fsp_pin)
+ {
+ return g_bsp_pin_cfg.p_pin_cfg_data[i].pin_cfg;
+ }
+ }
+
+ return 0;
+}
+
+static rt_bool_t ra_gpio_flags_are_valid(rt_uint32_t flags)
+{
+ rt_uint32_t bias = flags & RT_GENMASK(6, 4);
+ rt_uint32_t drive = flags & (PIN_SINGLE_ENDED | PIN_LINE_OPEN_DRAIN);
+ rt_uint32_t supported = PIN_ACTIVE_LOW | PIN_OPEN_DRAIN |
+ PIN_PULL_UP | PIN_PULL_DISABLE;
+
+ if (flags & ~supported)
+ {
+ return RT_FALSE;
+ }
+ if (drive && drive != PIN_OPEN_DRAIN)
+ {
+ return RT_FALSE;
+ }
+ if (drive && bias)
+ {
+ return RT_FALSE;
+ }
+ if (bias && bias != PIN_PULL_UP && bias != PIN_PULL_DISABLE)
+ {
+ return RT_FALSE;
+ }
+
+ return RT_TRUE;
+}
+
+static void ra_gpio_mode(struct rt_device *device, rt_base_t pin,
+ rt_uint8_t mode)
+{
+ fsp_err_t err;
+ rt_uint32_t cfg;
+ struct ra_gpio *gpio = device_to_ra_gpio(device);
+
+ if (!ra_gpio_pin_is_valid(gpio, pin))
+ {
+ return;
+ }
+
+ switch (mode)
+ {
+ case PIN_MODE_OUTPUT:
+ cfg = IOPORT_CFG_PORT_DIRECTION_OUTPUT;
+ break;
+
+ case PIN_MODE_INPUT:
+ cfg = IOPORT_CFG_PORT_DIRECTION_INPUT;
+ break;
+
+ case PIN_MODE_INPUT_PULLUP:
+ cfg = IOPORT_CFG_PORT_DIRECTION_INPUT | IOPORT_CFG_PULLUP_ENABLE;
+ break;
+
+ case PIN_MODE_OUTPUT_OD:
+ cfg = IOPORT_CFG_PORT_DIRECTION_OUTPUT | IOPORT_CFG_NMOS_ENABLE;
+ break;
+
+ case PIN_MODE_INPUT_PULLDOWN:
+ default:
+ LOG_E("P%u%02d mode %u is unsupported", gpio->port, pin, mode);
+ return;
+ }
+
+ if (gpio->irqs[pin].external_irq)
+ {
+ cfg |= IOPORT_CFG_IRQ_ENABLE;
+ }
+ cfg |= gpio->pin_cfg[pin] & IOPORT_CFG_DRIVE_HIGH;
+
+ err = R_IOPORT_PinCfg(&g_ioport_ctrl, ra_gpio_fsp_pin(gpio, pin), cfg);
+ if (err != FSP_SUCCESS)
+ {
+ LOG_E("P%u%02d configure failed: %d", gpio->port, pin, err);
+ return;
+ }
+
+ gpio->pin_cfg[pin] = cfg;
+}
+
+static void ra_gpio_write(struct rt_device *device, rt_base_t pin,
+ rt_uint8_t value)
+{
+ struct ra_gpio *gpio = device_to_ra_gpio(device);
+
+ if (ra_gpio_pin_is_valid(gpio, pin) &&
+ R_IOPORT_PinWrite(&g_ioport_ctrl, ra_gpio_fsp_pin(gpio, pin),
+ value == PIN_LOW ? BSP_IO_LEVEL_LOW : BSP_IO_LEVEL_HIGH) !=
+ FSP_SUCCESS)
+ {
+ LOG_E("P%u%02d write failed", gpio->port, pin);
+ }
+}
+
+static rt_ssize_t ra_gpio_read(struct rt_device *device, rt_base_t pin)
+{
+ fsp_err_t err;
+ bsp_io_level_t level;
+ struct ra_gpio *gpio = device_to_ra_gpio(device);
+
+ if (!ra_gpio_pin_is_valid(gpio, pin))
+ {
+ return -RT_EINVAL;
+ }
+
+ err = R_IOPORT_PinRead(&g_ioport_ctrl, ra_gpio_fsp_pin(gpio, pin), &level);
+ if (err != FSP_SUCCESS)
+ {
+ return -RT_EIO;
+ }
+
+ return level == BSP_IO_LEVEL_LOW ? PIN_LOW : PIN_HIGH;
+}
+
+static void ra_gpio_irq_handler(int vector, void *param)
+{
+ struct ra_gpio_irq *irq = param;
+
+ RT_UNUSED(vector);
+
+ if (irq->handler)
+ {
+ irq->handler(irq->args);
+ }
+}
+
+static rt_err_t ra_gpio_attach_irq(struct rt_device *device, rt_base_t pin,
+ rt_uint8_t mode, void (*handler)(void *args), void *args)
+{
+ struct ra_gpio_irq *irq;
+ struct ra_gpio *gpio = device_to_ra_gpio(device);
+
+ if (!ra_gpio_pin_is_valid(gpio, pin) || !handler ||
+ !(irq = &gpio->irqs[pin])->external_irq)
+ {
+ return -RT_EINVAL;
+ }
+
+ if (irq->handler && (irq->handler != handler || irq->args != args ||
+ irq->mode != mode))
+ {
+ return -RT_EBUSY;
+ }
+
+ irq->mode = mode;
+ irq->handler = handler;
+ irq->args = args;
+
+ return RT_EOK;
+}
+
+static rt_err_t ra_gpio_irq_enable(struct rt_device *device, rt_base_t pin,
+ rt_uint8_t enabled)
+{
+ rt_err_t err, cleanup_err;
+ struct ra_gpio_irq *irq;
+ struct ra_gpio *gpio = device_to_ra_gpio(device);
+
+ if (!ra_gpio_pin_is_valid(gpio, pin) ||
+ !(irq = &gpio->irqs[pin])->external_irq)
+ {
+ return -RT_EINVAL;
+ }
+
+ if (enabled == PIN_IRQ_ENABLE)
+ {
+ if (!irq->handler)
+ {
+ return -RT_EINVAL;
+ }
+ if (irq->enabled)
+ {
+ return RT_EOK;
+ }
+
+ if (!irq->acquired)
+ {
+ irq->irq = ra_external_irq_acquire(irq->external_irq,
+ gpio->port, pin, irq->mode);
+ if (irq->irq < 0)
+ {
+ return irq->irq;
+ }
+ irq->acquired = RT_TRUE;
+ }
+
+ if (!irq->pic_attached)
+ {
+ err = rt_pic_attach_irq(irq->irq, ra_gpio_irq_handler, irq,
+ "ra-gpio", RT_IRQ_F_NONE);
+ if (err)
+ {
+ cleanup_err = ra_external_irq_release(irq->external_irq,
+ gpio->port, pin);
+ if (!cleanup_err)
+ {
+ irq->acquired = RT_FALSE;
+ irq->irq = -1;
+ }
+ return cleanup_err ? cleanup_err : err;
+ }
+ irq->pic_attached = RT_TRUE;
+ }
+
+ err = ra_external_irq_enable(irq->external_irq, gpio->port, pin);
+ if (err)
+ {
+ cleanup_err = rt_pic_detach_irq(irq->irq, irq);
+ if (cleanup_err)
+ {
+ return cleanup_err;
+ }
+ irq->pic_attached = RT_FALSE;
+
+ cleanup_err = ra_external_irq_release(irq->external_irq,
+ gpio->port, pin);
+ if (!cleanup_err)
+ {
+ irq->acquired = RT_FALSE;
+ irq->irq = -1;
+ }
+ return cleanup_err ? cleanup_err : err;
+ }
+
+ irq->enabled = RT_TRUE;
+ }
+ else if (enabled == PIN_IRQ_DISABLE)
+ {
+ if (!irq->acquired && !irq->pic_attached)
+ {
+ irq->enabled = RT_FALSE;
+ return RT_EOK;
+ }
+
+ if (irq->enabled &&
+ (err = ra_external_irq_disable(irq->external_irq,
+ gpio->port, pin)))
+ {
+ return err;
+ }
+ irq->enabled = RT_FALSE;
+
+ if (irq->pic_attached)
+ {
+ err = rt_pic_detach_irq(irq->irq, irq);
+ if (err)
+ {
+ cleanup_err = ra_external_irq_enable(irq->external_irq,
+ gpio->port, pin);
+ if (!cleanup_err)
+ {
+ irq->enabled = RT_TRUE;
+ }
+ return cleanup_err ? cleanup_err : err;
+ }
+ irq->pic_attached = RT_FALSE;
+ }
+
+ if (irq->acquired)
+ {
+ err = ra_external_irq_release(irq->external_irq,
+ gpio->port, pin);
+ if (err)
+ {
+ cleanup_err = rt_pic_attach_irq(irq->irq,
+ ra_gpio_irq_handler, irq, "ra-gpio", RT_IRQ_F_NONE);
+ if (cleanup_err)
+ {
+ return cleanup_err;
+ }
+ irq->pic_attached = RT_TRUE;
+
+ cleanup_err = ra_external_irq_enable(irq->external_irq,
+ gpio->port, pin);
+ if (!cleanup_err)
+ {
+ irq->enabled = RT_TRUE;
+ }
+ return cleanup_err ? cleanup_err : err;
+ }
+ irq->acquired = RT_FALSE;
+ irq->irq = -1;
+ }
+ }
+ else
+ {
+ return -RT_EINVAL;
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t ra_gpio_detach_irq(struct rt_device *device, rt_base_t pin)
+{
+ rt_err_t err;
+ struct ra_gpio_irq *irq;
+ struct ra_gpio *gpio = device_to_ra_gpio(device);
+
+ if (!ra_gpio_pin_is_valid(gpio, pin))
+ {
+ return -RT_EINVAL;
+ }
+
+ irq = &gpio->irqs[pin];
+ if ((irq->enabled || irq->pic_attached || irq->acquired) &&
+ (err = ra_gpio_irq_enable(device, pin, PIN_IRQ_DISABLE)))
+ {
+ return err;
+ }
+
+ irq->handler = RT_NULL;
+ irq->args = RT_NULL;
+ irq->mode = 0;
+
+ return RT_EOK;
+}
+
+static rt_ssize_t ra_gpio_parse(struct rt_device *device,
+ struct rt_ofw_cell_args *args, rt_uint32_t *flags)
+{
+ struct ra_gpio *gpio = device_to_ra_gpio(device);
+
+ if (args->args_count != 2 || args->args[0] >= gpio->ngpios ||
+ !ra_gpio_flags_are_valid(args->args[1]))
+ {
+ return -RT_EINVAL;
+ }
+
+ if (flags)
+ {
+ *flags = args->args[1];
+ }
+
+ return args->args[0];
+}
+
+static const struct rt_pin_ops ra_gpio_ops = {
+ .pin_mode = ra_gpio_mode,
+ .pin_write = ra_gpio_write,
+ .pin_read = ra_gpio_read,
+ .pin_attach_irq = ra_gpio_attach_irq,
+ .pin_detach_irq = ra_gpio_detach_irq,
+ .pin_irq_enable = ra_gpio_irq_enable,
+ .pin_parse = ra_gpio_parse,
+};
+
+static rt_err_t ra_gpio_parse_port_irqs(struct ra_gpio *gpio,
+ struct rt_ofw_node *np)
+{
+ int irq_count = 0;
+ struct rt_ofw_node *irq_np;
+
+ while ((irq_np = rt_ofw_parse_phandle(np, "port-irqs", irq_count)))
+ {
+ int pin_count;
+ const char *irq_name;
+ char pins_prop[48];
+ struct ra_external_irq *external_irq;
+
+ if (rt_ofw_prop_read_string_index(np, "port-irq-names", irq_count,
+ &irq_name) ||
+ !(external_irq = ra_external_irq_get(irq_np)))
+ {
+ rt_ofw_node_put(irq_np);
+ return -RT_EINVAL;
+ }
+
+ rt_snprintf(pins_prop, sizeof(pins_prop), "port-%s-pins", irq_name);
+ pin_count = rt_ofw_prop_count_of_size(np, pins_prop,
+ sizeof(fdt32_t));
+ if (pin_count <= 0)
+ {
+ rt_ofw_node_put(irq_np);
+ return -RT_EINVAL;
+ }
+
+ for (int i = 0; i < pin_count; ++i)
+ {
+ rt_uint32_t pin;
+
+ if (rt_ofw_prop_read_u32_index(np, pins_prop, i, &pin) ||
+ pin >= gpio->ngpios || gpio->irqs[pin].external_irq)
+ {
+ rt_ofw_node_put(irq_np);
+ return -RT_EINVAL;
+ }
+ gpio->irqs[pin].external_irq = external_irq;
+ }
+
+ rt_ofw_node_put(irq_np);
+ ++irq_count;
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t ra_gpio_probe(struct rt_platform_device *pdev)
+{
+ rt_err_t err;
+ rt_uint32_t port, ngpios = RA_GPIO_PIN_NR;
+ rt_uint64_t address, size;
+ struct rt_device *dev = &pdev->parent;
+ struct ra_gpio *gpio = rt_calloc(1, sizeof(*gpio));
+
+ if (!gpio)
+ {
+ return -RT_ENOMEM;
+ }
+
+ if ((err = rt_ofw_get_address(dev->ofw_node, 0, &address, &size)) ||
+ !size ||
+ (err = rt_ofw_prop_read_u32(dev->ofw_node, "port", &port)) ||
+ port > 13)
+ {
+ err = err ? err : -RT_EINVAL;
+ goto _fail;
+ }
+ if (address != 0x40400000UL + port * 0x20UL)
+ {
+ err = -RT_EINVAL;
+ goto _fail;
+ }
+
+ rt_ofw_prop_read_u32(dev->ofw_node, "ngpios", &ngpios);
+ if (!ngpios || ngpios > RA_GPIO_PIN_NR)
+ {
+ err = -RT_EINVAL;
+ goto _fail;
+ }
+
+ gpio->port = port;
+ gpio->ngpios = ngpios;
+ for (int i = 0; i < gpio->ngpios; ++i)
+ {
+ gpio->pin_cfg[i] = ra_gpio_board_pin_cfg(gpio, i);
+ gpio->irqs[i].irq = -1;
+ }
+
+ if ((err = ra_gpio_parse_port_irqs(gpio, dev->ofw_node)))
+ {
+ goto _fail;
+ }
+
+ gpio->parent.ops = &ra_gpio_ops;
+ if ((err = pin_api_init(&gpio->parent, gpio->ngpios)))
+ {
+ goto _fail;
+ }
+
+ rt_dm_dev_bind_fwdata(dev, RT_NULL, &gpio->parent);
+ pdev->priv = gpio;
+
+ return RT_EOK;
+
+_fail:
+ rt_free(gpio);
+
+ return err;
+}
+
+static const struct rt_ofw_node_id ra_gpio_ofw_ids[] = {
+ { .compatible = "renesas,ra-gpio-ioport" },
+ { /* sentinel */ }
+};
+
+static struct rt_platform_driver ra_gpio_driver = {
+ .name = "ra-gpio-ioport",
+ .ids = ra_gpio_ofw_ids,
+ .probe = ra_gpio_probe,
+};
+RT_PLATFORM_DRIVER_EXPORT(ra_gpio_driver);
diff --git a/bsp/renesas/libraries/HAL_Drivers/drv_common.c b/bsp/renesas/libraries/HAL_Drivers/drv_common.c
index b85e180cba..ece40d59bf 100644
--- a/bsp/renesas/libraries/HAL_Drivers/drv_common.c
+++ b/bsp/renesas/libraries/HAL_Drivers/drv_common.c
@@ -13,8 +13,15 @@
#include "board.h"
#include <hal_data.h>
-#ifdef RT_USING_PIN
- #include <drv_gpio.h>
+#ifdef RT_USING_BUILTIN_FDT
+#include <drivers/ofw_fdt.h>
+#include <drivers/pic.h>
+
+extern const unsigned char rt_hw_builtin_fdt[];
+#endif
+
+#if defined(RT_USING_PIN) && !defined(RT_USING_DM)
+#include <drv_gpio.h>
#endif
#ifdef RT_USING_SERIAL
@@ -183,8 +190,25 @@ rt_weak void rt_hw_board_init()
rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);
#endif
+#ifdef RT_USING_BUILTIN_FDT
+ if (rt_fdt_prefetch((void *)rt_hw_builtin_fdt) != RT_EOK ||
+ rt_fdt_unflatten() != RT_EOK)
+ {
+ rt_kprintf("Builtin FDT initialization failed\n");
+ RT_ASSERT(0);
+ }
+
+#ifdef RT_USING_PIC
+ if (rt_pic_init() != RT_EOK || rt_pic_irq_init() != RT_EOK)
+ {
+ rt_kprintf("PIC initialization failed\n");
+ RT_ASSERT(0);
+ }
+#endif
+#endif
+
/* Pin driver initialization is open by default */
-#ifdef RT_USING_PIN
+#if defined(RT_USING_PIN) && !defined(RT_USING_DM)
rt_hw_pin_init();
#endif
diff --git a/bsp/renesas/ra8p1-titan-board/README.md b/bsp/renesas/ra8p1-titan-board/README.md
index c9522cde80..09229f406f 100644
--- a/bsp/renesas/ra8p1-titan-board/README.md
+++ b/bsp/renesas/ra8p1-titan-board/README.md
@@ -250,6 +250,16 @@ In **RT-Thread Settings**, you can configure the RT-Thread kernel, components, s
![image-20250819173700386](m85/figures/image-20250819173700386.png)
+### Enabling the Device Model (DM)
+
+The current DM GPIO and external-interrupt support targets the `m85` project. The `m33` project continues to use the legacy BSP drivers. The `m85` project uses `RT_USING_DM` to select one driver framework, so the DM and legacy drivers for the same GPIO controller are not built together.
+
+1. Enter the `m85` directory and run `scons --menuconfig`.
+2. Open `Device Drivers` and enable `Enable device driver model with device tree`.
+3. Save the configuration and run `scons -jN` for a GCC build.
+
+The BSP automatically selects OFW, built-in FDT, PIC, NVIC, and PIN support with `RT_USING_DM`, and uses `m85/board/dts/ra8p1-titan-m85.dts`. The build converts and embeds the DTB automatically.
+
## Contact Information
If you have any thoughts or suggestions during usage, please feel free to contact us via the [RT-Thread Community Forum](https://club.rt-thread.org/).
diff --git a/bsp/renesas/ra8p1-titan-board/README_zh.md b/bsp/renesas/ra8p1-titan-board/README_zh.md
index 2eb340e9a4..380b3fc0de 100644
--- a/bsp/renesas/ra8p1-titan-board/README_zh.md
+++ b/bsp/renesas/ra8p1-titan-board/README_zh.md
@@ -248,6 +248,16 @@ void hal_entry(void)
![image-20250819173700386](m85/figures/image-20250819173700386.png)
+### 启用设备模型(DM)
+
+当前 DM GPIO 和外部中断适配用于 `m85` 工程,`m33` 工程仍使用传统 BSP 驱动。`m85` 通过 `RT_USING_DM` 在两套驱动之间进行选择,不能同时构建同一个 GPIO 控制器的 DM 驱动和传统驱动。
+
+1. 进入 `m85` 目录并执行 `scons --menuconfig`。
+2. 进入 `Device Drivers`,选中 `Enable device driver model with device tree`。
+3. 保存配置后执行 `scons -jN` 构建 GCC 工程。
+
+BSP 会随 `RT_USING_DM` 自动选择 OFW、内置 FDT、PIC、NVIC 和 PIN 框架,并使用 `m85/board/dts/ra8p1-titan-m85.dts`。构建过程会生成并嵌入 DTB。
+
## 联系人信息
在使用过程中若您有任何的想法和建议,建议您通过以下方式来联系到我们 [RT-Thread 社区论坛](https://club.rt-thread.org/)
diff --git a/bsp/renesas/ra8p1-titan-board/m85/.settings/standalone.prefs b/bsp/renesas/ra8p1-titan-board/m85/.settings/standalone.prefs
index 750d5315c4..9b67bd7db2 100644
--- a/bsp/renesas/ra8p1-titan-board/m85/.settings/standalone.prefs
+++ b/bsp/renesas/ra8p1-titan-board/m85/.settings/standalone.prefs
@@ -25,6 +25,8 @@ com.renesas.cdt.ddsc.packs.componentfiles/Renesas\#\#HAL\ Drivers\#\#all\#\#r_dm
com.renesas.cdt.ddsc.packs.componentfiles/Renesas\#\#HAL\ Drivers\#\#all\#\#r_dmac\#\#\#\#6.2.0/libraries=
com.renesas.cdt.ddsc.packs.componentfiles/Renesas\#\#HAL\ Drivers\#\#all\#\#r_gpt\#\#\#\#6.2.0/all=2496371585,ra/fsp/inc/api/r_timer_api.h|1024386857,ra/fsp/inc/instances/r_gpt.h|897288737,ra/fsp/src/r_gpt/r_gpt.c
com.renesas.cdt.ddsc.packs.componentfiles/Renesas\#\#HAL\ Drivers\#\#all\#\#r_gpt\#\#\#\#6.2.0/libraries=
+com.renesas.cdt.ddsc.packs.componentfiles/Renesas\#\#HAL\ Drivers\#\#all\#\#r_icu\#\#\#\#6.2.0/all=3851692545,ra/fsp/inc/api/r_external_irq_api.h|677149658,ra/fsp/inc/instances/r_icu.h|3443785969,ra/fsp/src/r_icu/r_icu.c
+com.renesas.cdt.ddsc.packs.componentfiles/Renesas\#\#HAL\ Drivers\#\#all\#\#r_icu\#\#\#\#6.2.0/libraries=
com.renesas.cdt.ddsc.packs.componentfiles/Renesas\#\#HAL\ Drivers\#\#all\#\#r_iic_master\#\#\#\#6.2.0/all=1589066529,ra/fsp/inc/api/r_elc_api.h|429738396,ra/fsp/inc/api/r_transfer_api.h|979139595,ra/fsp/inc/api/r_i2c_master_api.h|2048414029,ra/fsp/inc/instances/r_iic_master.h|4191706256,ra/fsp/src/r_iic_master/r_iic_master.c
com.renesas.cdt.ddsc.packs.componentfiles/Renesas\#\#HAL\ Drivers\#\#all\#\#r_iic_master\#\#\#\#6.2.0/libraries=
com.renesas.cdt.ddsc.packs.componentfiles/Renesas\#\#HAL\ Drivers\#\#all\#\#r_ioport\#\#\#\#6.2.0/all=1692739955,ra/fsp/inc/api/r_ioport_api.h|2533231413,ra/fsp/inc/instances/r_ioport.h|2765953787,ra/fsp/src/r_ioport/r_ioport.c
diff --git a/bsp/renesas/ra8p1-titan-board/m85/Kconfig b/bsp/renesas/ra8p1-titan-board/m85/Kconfig
index 85230cecf1..27aa3aab04 100644
--- a/bsp/renesas/ra8p1-titan-board/m85/Kconfig
+++ b/bsp/renesas/ra8p1-titan-board/m85/Kconfig
@@ -17,9 +17,19 @@ config SOC_R7KA8P1KF
select SOC_SERIES_R7KA8P1_CORE0
select RT_USING_COMPONENTS_INIT
select RT_USING_USER_MAIN
+ select RT_USING_OFW if RT_USING_DM
+ select RT_USING_BUILTIN_FDT if RT_USING_DM
+ select RT_USING_PIC if RT_USING_DM
+ select RT_PIC_ARM_NVIC if RT_USING_DM
+ select RT_USING_PIN if RT_USING_DM
default y
+config RT_BUILTIN_FDT_PATH
+ string
+ default "board/dts/ra8p1-titan-m85.dtb" if RT_USING_DM
+
source "$(RTT_DIR)/Kconfig"
+
osource "$PKGS_DIR/Kconfig"
rsource "../../libraries/Kconfig"
diff --git a/bsp/renesas/ra8p1-titan-board/m85/SConstruct b/bsp/renesas/ra8p1-titan-board/m85/SConstruct
index ec8c43740c..2139cfcbbc 100644
--- a/bsp/renesas/ra8p1-titan-board/m85/SConstruct
+++ b/bsp/renesas/ra8p1-titan-board/m85/SConstruct
@@ -10,6 +10,7 @@ else:
sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
try:
from building import *
+ import dtc
except:
print('Cannot found RT-Thread root directory, please check RTT_ROOT')
print(RTT_ROOT)
@@ -34,6 +35,8 @@ if rtconfig.PLATFORM in ['iccarm']:
Export('RTT_ROOT')
Export('rtconfig')
+BSP_ROOT = os.path.abspath('./')
+env.Prepend(CPPPATH=[os.path.join(BSP_ROOT, 'board')])
SDK_ROOT = os.path.abspath('./..')
if os.path.exists(SDK_ROOT + '/libraries'):
libraries_path_prefix = SDK_ROOT + '/libraries'
@@ -48,6 +51,28 @@ rtconfig.BSP_LIBRARY_TYPE = None
# prepare building environment
objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False)
+if GetDepend('RT_USING_BUILTIN_FDT'):
+ if os.getenv('DTC_PATH'):
+ os.environ['PATH'] = os.path.dirname(os.getenv('DTC_PATH')) + \
+ os.pathsep + os.environ['PATH']
+
+ dtb_name = GetDepend('RT_BUILTIN_FDT_PATH').strip('"')
+ dts_name = os.path.splitext(dtb_name)[0] + '.dts'
+ dts_path = os.path.join(BSP_ROOT, dts_name)
+ dtc.dts_to_dtb(RTT_ROOT, [dts_name],
+ include_paths=[os.path.dirname(dts_path)])
+
+ if rtconfig.PLATFORM == 'gcc':
+ dtb_path = os.path.join(BSP_ROOT, dtb_name)
+ fdt_source = os.path.join(libraries_path_prefix, 'HAL_Drivers',
+ 'drivers', 'dm', 'builtin_fdt_gcc.S')
+ fdt_object = env.Object(
+ target=os.path.join(BSP_ROOT, 'build', 'dts',
+ 'builtin_fdt_gcc.o'),
+ source=fdt_source)
+ env.Depends(fdt_object, dtb_path)
+ objs += fdt_object
+
# include drivers
objs.extend(SConscript(os.path.join(libraries_path_prefix, 'HAL_Drivers', 'SConscript'),
variant_dir='build/libraries/HAL_Drivers', duplicate=0))
diff --git a/bsp/renesas/ra8p1-titan-board/m85/board/dts/ra8p1-titan-m85.dts b/bsp/renesas/ra8p1-titan-board/m85/board/dts/ra8p1-titan-m85.dts
new file mode 100644
index 0000000000..5ad720f386
--- /dev/null
+++ b/bsp/renesas/ra8p1-titan-board/m85/board/dts/ra8p1-titan-m85.dts
@@ -0,0 +1,74 @@
+/dts-v1/;
+
+#include <dt-bindings/pin/pin.h>
+
+/ {
+ compatible = "rt-thread,ra8p1-titan-board", "renesas,ra8p1";
+ model = "RT-Thread RA8P1 Titan Board M85";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aliases {
+ };
+
+ chosen {
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ compatible = "arm,cortex-m85";
+ device_type = "cpu";
+ reg = <0>;
+ };
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ interrupt-parent = <&nvic>;
+
+ nvic: interrupt-controller@e000e100 {
+ compatible = "arm,v8m-nvic";
+ reg = <0xe000e100 0xc00>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ arm,num-irqs = <96>;
+ arm,num-irq-priority-bits = <4>;
+ };
+
+ externalirq20: external-interrupt@40006018 {
+ compatible = "renesas,ra-external-interrupt";
+ reg = <0x40006018 0x1>;
+ interrupts = <49 12>;
+ channel = <20>;
+ renesas,trigger = "falling";
+ renesas,sample-clock-div = <64>;
+ };
+
+ ioport1: gpio@40400020 {
+ compatible = "renesas,ra-gpio-ioport";
+ reg = <0x40400020 0x20>;
+ port = <1>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ ngpios = <16>;
+ port-irqs = <&externalirq20>;
+ port-irq-names = "irq20";
+ port-irq20-pins = <10>;
+ };
+
+ ioport0: gpio@40400000 {
+ compatible = "renesas,ra-gpio-ioport";
+ reg = <0x40400000 0x20>;
+ port = <0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ ngpios = <16>;
+ };
+ };
+};
diff --git a/bsp/renesas/ra8p1-titan-board/m85/configuration.xml b/bsp/renesas/ra8p1-titan-board/m85/configuration.xml
index ab41e10970..500d99103a 100644
--- a/bsp/renesas/ra8p1-titan-board/m85/configuration.xml
+++ b/bsp/renesas/ra8p1-titan-board/m85/configuration.xml
@@ -494,6 +494,10 @@
<description>Serial Peripheral Interface</description>
<originalPack>Renesas.RA.6.2.0.pack</originalPack>
</component>
+ <component apiversion="" class="HAL Drivers" condition="" group="all" subgroup="r_icu" variant="" vendor="Renesas" version="6.2.0">
+ <description>External Interrupt</description>
+ <originalPack>Renesas.RA.6.2.0.pack</originalPack>
+ </component>
</raComponentSelection>
<raElcConfiguration/>
<raIcuConfiguration/>
@@ -1749,6 +1753,16 @@
<property id="module.driver.uart.tei_ipl" value="board.icu.common.irq.priority12"/>
<property id="module.driver.uart.eri_ipl" value="board.icu.common.irq.priority12"/>
</module>
+ <module id="module.driver.external_irq_on_icu.462017933">
+ <property id="module.driver.external_irq.name" value="g_external_irq20"/>
+ <property id="module.driver.external_irq.channel" value="20"/>
+ <property id="module.driver.external_irq.trigger" value="module.driver.external_irq.trigger.trig_falling"/>
+ <property id="module.driver.external_irq.filter_enable" value="module.driver.external_irq.filter_enable.false"/>
+ <property id="module.driver.external_irq.filter_source" value="module.driver.external_irq.filter_source.pclk"/>
+ <property id="module.driver.external_irq.clock_source_div" value="module.driver.external_irq.clock_source_div.clock_source_div_by_64"/>
+ <property id="module.driver.external_irq.p_callback" value="irq_callback"/>
+ <property id="module.driver.external_irq.ipl" value="board.icu.common.irq.priority12"/>
+ </module>
<context id="_hal.0">
<stack module="module.driver.ioport_on_ioport.0"/>
<stack module="module.driver.uart_on_sci_b_uart.115874252"/>
@@ -1774,6 +1788,7 @@
<stack module="module.driver.i2c_on_iic_master.2129583021"/>
<stack module="module.driver.spi_on_spi_b.2079125247"/>
<stack module="module.driver.uart_on_sci_b_uart.404954056"/>
+ <stack module="module.driver.external_irq_on_icu.462017933"/>
</context>
<config id="config.driver.ospi_b">
<property id="config.driver.ospi_b.param_checking_enable" value="config.driver.ospi_b.param_checking_enable.bsp"/>
@@ -1841,6 +1856,9 @@
<property id="config.driver.ioport.checking" value="config.driver.ioport.checking.system"/>
<property id="config.driver.ioport.ccd_support_enable" value="config.driver.ioport.ccd_support_enable.disabled"/>
</config>
+ <config id="config.driver.icu">
+ <property id="config.driver.icu.param_checking_enable" value="config.driver.icu.param_checking_enable.bsp"/>
+ </config>
<config id="config.driver.rtc">
<property id="config.driver.rtc.param_checking_enable" value="config.driver.rtc.param_checking_enable.bsp"/>
<property id="config.driver.rtc.open_set_source_clock" value="config.driver.rtc.open_set_source_clock.enabled"/>
@@ -2190,6 +2208,8 @@
<configSetting altId="iic2.mode.custom.free" configurationId="iic2.mode"/>
<configSetting altId="iic2.scl2.p709" configurationId="iic2.scl2"/>
<configSetting altId="iic2.sda2.p708" configurationId="iic2.sda2"/>
+ <configSetting altId="irq.irq20.p110" configurationId="irq.irq20"/>
+ <configSetting altId="irq.mode.custom.free" configurationId="irq.mode"/>
<configSetting altId="ospi1.mode.custom.free" configurationId="ospi1.mode"/>
<configSetting altId="ospi1.om_1_cs0.pc08" configurationId="ospi1.om_1_cs0"/>
<configSetting altId="ospi1.om_1_dqs.p607" configurationId="ospi1.om_1_dqs"/>
@@ -2233,6 +2253,9 @@
<configSetting altId="p108.gpio_mode.gpio_mode_peripheral" configurationId="p108.gpio_mode"/>
<configSetting altId="p109.gpt10.gtioc10a" configurationId="p109"/>
<configSetting altId="p109.gpio_mode.gpio_mode_peripheral" configurationId="p109.gpio_mode"/>
+ <configSetting altId="p110.irq.irq20" configurationId="p110"/>
+ <configSetting altId="p110.gpio_irq.gpio_irq_enabled" configurationId="p110.gpio_irq"/>
+ <configSetting altId="p110.gpio_mode.gpio_mode_irq" configurationId="p110.gpio_mode"/>
<configSetting altId="p111.sdhi0.sd0dat3" configurationId="p111"/>
<configSetting altId="p111.gpio_mode.gpio_mode_peripheral" configurationId="p111.gpio_mode"/>
<configSetting altId="p112.sci0.txd0" configurationId="p112"/>
diff --git a/bsp/renesas/ra8p1-titan-board/m85/ra/fsp/inc/api/r_external_irq_api.h b/bsp/renesas/ra8p1-titan-board/m85/ra/fsp/inc/api/r_external_irq_api.h
new file mode 100644
index 0000000000..e709473c1d
--- /dev/null
+++ b/bsp/renesas/ra8p1-titan-board/m85/ra/fsp/inc/api/r_external_irq_api.h
@@ -0,0 +1,154 @@
+/*
+* Copyright (c) 2020 - 2025 Renesas Electronics Corporation and/or its affiliates
+*
+* SPDX-License-Identifier: BSD-3-Clause
+*/
+
+/*******************************************************************************************************************//**
+ * @ingroup RENESAS_INPUT_INTERFACES
+ * @defgroup EXTERNAL_IRQ_API External IRQ Interface
+ * @brief Interface for detecting external interrupts.
+ *
+ * @section EXTERNAL_IRQ_API_Summary Summary
+ * The External IRQ Interface is for configuring interrupts to fire when a trigger condition is detected on an
+ * external IRQ pin.
+ *
+ *
+ * @{
+ **********************************************************************************************************************/
+
+#ifndef R_EXTERNAL_IRQ_API_H
+#define R_EXTERNAL_IRQ_API_H
+
+/***********************************************************************************************************************
+ * Includes
+ **********************************************************************************************************************/
+
+/* Includes board and MCU related header files. */
+#include "bsp_api.h"
+
+/* Common macro for FSP header files. There is also a corresponding FSP_FOOTER macro at the end of this file. */
+FSP_HEADER
+
+/**********************************************************************************************************************
+ * Macro definitions
+ *********************************************************************************************************************/
+
+/*********************************************************************************************************************
+ * Typedef definitions
+ *********************************************************************************************************************/
+
+/** Callback function parameter data */
+typedef struct st_external_irq_callback_args
+{
+ /** Placeholder for user data. Set in @ref external_irq_api_t::open function in @ref external_irq_cfg_t. */
+ void * p_context;
+ uint32_t channel; ///< The physical hardware channel that caused the interrupt.
+} external_irq_callback_args_t;
+
+#ifndef BSP_OVERRIDE_EXTERNAL_IRQ_TRIGGER_T
+
+/** Condition that will trigger an interrupt when detected. */
+typedef enum e_external_irq_trigger
+{
+ EXTERNAL_IRQ_TRIG_FALLING = 0, ///< Falling edge trigger
+ EXTERNAL_IRQ_TRIG_RISING = 1, ///< Rising edge trigger
+ EXTERNAL_IRQ_TRIG_BOTH_EDGE = 2, ///< Both edges trigger
+ EXTERNAL_IRQ_TRIG_LEVEL_LOW = 3, ///< Low level trigger
+ EXTERNAL_IRQ_TRIG_LEVEL_HIGH = 4 ///< High level trigger
+} external_irq_trigger_t;
+#endif
+
+#ifndef BSP_OVERRIDE_EXTERNAL_IRQ_PCLK_DIV_T
+
+/** External IRQ input pin digital filtering sample clock divisor settings. The digital filter rejects trigger
+ * conditions that are shorter than 3 periods of the filter clock.
+ */
+typedef enum e_external_irq_clock_source_div
+{
+ EXTERNAL_IRQ_CLOCK_SOURCE_DIV_1 = 0, ///< Filter using clock source divided by 1
+ EXTERNAL_IRQ_CLOCK_SOURCE_DIV_8 = 1, ///< Filter using clock source divided by 8
+ EXTERNAL_IRQ_CLOCK_SOURCE_DIV_32 = 2, ///< Filter using clock source divided by 32
+ EXTERNAL_IRQ_CLOCK_SOURCE_DIV_64 = 3, ///< Filter using clock source divided by 64
+} external_irq_clock_source_div_t;
+#endif
+
+/** User configuration structure, used in open function */
+typedef struct st_external_irq_cfg
+{
+ uint8_t channel; ///< Hardware channel used.
+ uint8_t ipl; ///< Interrupt priority
+ IRQn_Type irq; ///< Interrupt number assigned to this instance
+ external_irq_trigger_t trigger; ///< Trigger setting.
+ external_irq_clock_source_div_t clock_source_div; ///< Digital filter clock divisor setting.
+ bool filter_enable; ///< Digital filter enable/disable selection.
+
+ /** Callback provided external input trigger occurs. */
+ void (* p_callback)(external_irq_callback_args_t * p_args);
+
+ /** Placeholder for user data. Passed to the user callback in @ref external_irq_callback_args_t. */
+ void * p_context;
+ void const * p_extend; ///< External IRQ hardware dependent configuration.
+} external_irq_cfg_t;
+
+/** External IRQ control block. Allocate an instance specific control block to pass into the external IRQ API calls.
+ */
+typedef void external_irq_ctrl_t;
+
+/** External interrupt driver structure. External interrupt functions implemented at the HAL layer will follow this API. */
+typedef struct st_external_irq_api
+{
+ /** Initial configuration.
+ *
+ * @param[out] p_ctrl Pointer to control block. Must be declared by user. Value set here.
+ * @param[in] p_cfg Pointer to configuration structure. All elements of the structure must be set by user.
+ */
+ fsp_err_t (* open)(external_irq_ctrl_t * const p_ctrl, external_irq_cfg_t const * const p_cfg);
+
+ /** Enable callback when an external trigger condition occurs.
+ *
+ * @param[in] p_ctrl Control block set in Open call for this external interrupt.
+ */
+ fsp_err_t (* enable)(external_irq_ctrl_t * const p_ctrl);
+
+ /** Disable callback when external trigger condition occurs.
+ *
+ * @param[in] p_ctrl Control block set in Open call for this external interrupt.
+ */
+ fsp_err_t (* disable)(external_irq_ctrl_t * const p_ctrl);
+
+ /**
+ * Specify callback function and optional context pointer and working memory pointer.
+ *
+ * @param[in] p_ctrl Pointer to the External IRQ control block.
+ * @param[in] p_callback Callback function
+ * @param[in] p_context Pointer to send to callback function
+ * @param[in] p_working_memory Pointer to volatile memory where callback structure can be allocated.
+ * Callback arguments allocated here are only valid during the callback.
+ */
+ fsp_err_t (* callbackSet)(external_irq_ctrl_t * const p_ctrl, void (* p_callback)(external_irq_callback_args_t *),
+ void * const p_context, external_irq_callback_args_t * const p_callback_memory);
+
+ /** Allow driver to be reconfigured. May reduce power consumption.
+ *
+ * @param[in] p_ctrl Control block set in Open call for this external interrupt.
+ */
+ fsp_err_t (* close)(external_irq_ctrl_t * const p_ctrl);
+} external_irq_api_t;
+
+/** This structure encompasses everything that is needed to use an instance of this interface. */
+typedef struct st_external_irq_instance
+{
+ external_irq_ctrl_t * p_ctrl; ///< Pointer to the control structure for this instance
+ external_irq_cfg_t const * p_cfg; ///< Pointer to the configuration structure for this instance
+ external_irq_api_t const * p_api; ///< Pointer to the API structure for this instance
+} external_irq_instance_t;
+
+/* Common macro for FSP header files. There is also a corresponding FSP_HEADER macro at the top of this file. */
+FSP_FOOTER
+
+/*******************************************************************************************************************//**
+ * @} (end defgroup EXTERNAL_IRQ_API)
+ **********************************************************************************************************************/
+
+#endif
diff --git a/bsp/renesas/ra8p1-titan-board/m85/ra/fsp/inc/instances/r_icu.h b/bsp/renesas/ra8p1-titan-board/m85/ra/fsp/inc/instances/r_icu.h
new file mode 100644
index 0000000000..1b265bed32
--- /dev/null
+++ b/bsp/renesas/ra8p1-titan-board/m85/ra/fsp/inc/instances/r_icu.h
@@ -0,0 +1,94 @@
+/*
+* Copyright (c) 2020 - 2025 Renesas Electronics Corporation and/or its affiliates
+*
+* SPDX-License-Identifier: BSD-3-Clause
+*/
+
+/*******************************************************************************************************************//**
+ * @addtogroup ICU
+ * @{
+ **********************************************************************************************************************/
+
+#ifndef R_ICU_H
+#define R_ICU_H
+
+/***********************************************************************************************************************
+ * Includes
+ **********************************************************************************************************************/
+#include "bsp_api.h"
+#include "r_external_irq_api.h"
+
+/* Common macro for FSP header files. There is also a corresponding FSP_FOOTER macro at the end of this file. */
+FSP_HEADER
+
+/***********************************************************************************************************************
+ * Macro definitions
+ **********************************************************************************************************************/
+
+/*********************************************************************************************************************
+ * Typedef definitions
+ *********************************************************************************************************************/
+
+/** External IRQ input pin digital filtering clock selection. */
+typedef enum e_external_irq_digital_filter
+{
+ EXTERNAL_IRQ_DIGITAL_FILTER_PCLK_DIV = 0, ///< Digital filter using clock PCLK dividers.
+ EXTERNAL_IRQ_DIGITAL_FILTER_LOCO = 1, ///< Digital filter using clock LOCO.
+} e_external_irq_digital_filter_t;
+
+/** Extended ICU interface configuration */
+typedef struct st_icu_extended_cfg
+{
+ e_external_irq_digital_filter_t filter_src; ///< Select digital filter clock source when digital filter is enabled.
+} icu_extended_cfg_t;
+
+/** ICU private control block. DO NOT MODIFY. Initialization occurs when R_ICU_ExternalIrqOpen is called. */
+typedef struct st_icu_instance_ctrl
+{
+ uint32_t open; ///< Used to determine if channel control block is in use
+ IRQn_Type irq; ///< NVIC interrupt number
+ uint8_t channel; ///< Channel
+
+#if BSP_TZ_SECURE_BUILD
+ external_irq_callback_args_t * p_callback_memory; // Pointer to non-secure memory that can be used to pass arguments to a callback in non-secure memory.
+#endif
+ void (* p_callback)(external_irq_callback_args_t * p_args); // Pointer to callback that is called when an edge is detected on the external irq pin.
+
+ /** Placeholder for user data. Passed to the user callback in ::external_irq_callback_args_t. */
+ void * p_context;
+} icu_instance_ctrl_t;
+
+/**********************************************************************************************************************
+ * Exported global variables
+ **********************************************************************************************************************/
+
+/** @cond INC_HEADER_DEFS_SEC */
+/** Filled in Interface API structure for this Instance. */
+extern const external_irq_api_t g_external_irq_on_icu;
+
+/** @endcond */
+
+/***********************************************************************************************************************
+ * Public APIs
+ **********************************************************************************************************************/
+fsp_err_t R_ICU_ExternalIrqOpen(external_irq_ctrl_t * const p_api_ctrl, external_irq_cfg_t const * const p_cfg);
+
+fsp_err_t R_ICU_ExternalIrqEnable(external_irq_ctrl_t * const p_api_ctrl);
+
+fsp_err_t R_ICU_ExternalIrqDisable(external_irq_ctrl_t * const p_api_ctrl);
+
+fsp_err_t R_ICU_ExternalIrqCallbackSet(external_irq_ctrl_t * const p_api_ctrl,
+ void ( * p_callback)(external_irq_callback_args_t *),
+ void * const p_context,
+ external_irq_callback_args_t * const p_callback_memory);
+
+fsp_err_t R_ICU_ExternalIrqClose(external_irq_ctrl_t * const p_api_ctrl);
+
+/*******************************************************************************************************************//**
+ * @} (end defgroup ICU)
+ **********************************************************************************************************************/
+
+/* Common macro for FSP header files. There is also a corresponding FSP_HEADER macro at the top of this file. */
+FSP_FOOTER
+
+#endif // R_ICU_H
diff --git a/bsp/renesas/ra8p1-titan-board/m85/ra/fsp/src/r_icu/r_icu.c b/bsp/renesas/ra8p1-titan-board/m85/ra/fsp/src/r_icu/r_icu.c
new file mode 100644
index 0000000000..6750e29154
--- /dev/null
+++ b/bsp/renesas/ra8p1-titan-board/m85/ra/fsp/src/r_icu/r_icu.c
@@ -0,0 +1,439 @@
+/*
+* Copyright (c) 2020 - 2025 Renesas Electronics Corporation and/or its affiliates
+*
+* SPDX-License-Identifier: BSD-3-Clause
+*/
+
+/***********************************************************************************************************************
+ * Includes
+ **********************************************************************************************************************/
+#include "r_icu.h"
+#include "r_icu_cfg.h"
+
+/***********************************************************************************************************************
+ * Macro definitions
+ **********************************************************************************************************************/
+
+/** "ICU" in ASCII, used to determine if channel is open. */
+#define ICU_OPEN (0x00494355U)
+
+#define ICU_IRQMD_OFFSET (0)
+
+#if BSP_FEATURE_ICU_HAS_FILTER
+ #define ICU_FCLKSEL_OFFSET (4)
+ #define ICU_FLTEN_OFFSET (7)
+ #if BSP_FEATURE_ICU_HAS_LOCO_FILTER
+ #define LOCO_CLOCK_HZ (R_BSP_SourceClockHzGet(FSP_PRIV_CLOCK_LOCO))
+ #define SYSTEM_CLOCK_HZ (SystemCoreClock)
+ #endif
+#endif
+
+/* If the mask is larger than 0xFFFF, then it requires 32-bit values instead of 16-bit */
+#if BSP_FEATURE_ICU_IRQ_CHANNELS_MASK > 0xFFFFU
+
+/* When mask is over 16-bit, there are actually two registers - R_ICU->IRQCRa and R_ICU->IRQCRb. Between them in memory
+ * is R_ICU->NMICR and means there is a 4 byte offset between the end of IRQCRa and beginning of IRQCRb. To save some
+ * instructions, this arithmetic determines if the 4 byte offset should be added to the indexing of IRQCRa to write to
+ * channels 16-31 */
+ #define ICU_IRQCR_CH(c) ((c) + (uint8_t) (((c) >> 4) << 2))
+ #define ICU_IRQCR_REG (R_ICU->IRQCRa)
+ #define ICU_IRQCR_REG_BITFIELD (R_ICU->IRQCRa_b)
+#else
+ #define ICU_IRQCR_CH(c) (c)
+ #define ICU_IRQCR_REG (R_ICU->IRQCR)
+ #define ICU_IRQCR_REG_BITFIELD (R_ICU->IRQCR_b)
+#endif
+
+/***********************************************************************************************************************
+ * Typedef definitions
+ **********************************************************************************************************************/
+
+#if defined(__ARMCC_VERSION) || defined(__ICCARM__)
+typedef void (BSP_CMSE_NONSECURE_CALL * icu_prv_ns_callback)(external_irq_callback_args_t * p_args);
+#elif defined(__GNUC__)
+typedef BSP_CMSE_NONSECURE_CALL void (*volatile icu_prv_ns_callback)(external_irq_callback_args_t * p_args);
+#endif
+
+/***********************************************************************************************************************
+ * Private function prototypes
+ **********************************************************************************************************************/
+void r_icu_isr(void);
+
+/***********************************************************************************************************************
+ * Private global variables
+ **********************************************************************************************************************/
+
+/***********************************************************************************************************************
+ * Global Variables
+ **********************************************************************************************************************/
+
+/* ICU implementation of External IRQ API. */
+const external_irq_api_t g_external_irq_on_icu =
+{
+ .open = R_ICU_ExternalIrqOpen,
+ .enable = R_ICU_ExternalIrqEnable,
+ .disable = R_ICU_ExternalIrqDisable,
+ .callbackSet = R_ICU_ExternalIrqCallbackSet,
+ .close = R_ICU_ExternalIrqClose,
+};
+
+/*******************************************************************************************************************//**
+ * @addtogroup ICU
+ * @{
+ **********************************************************************************************************************/
+
+/***********************************************************************************************************************
+ * Functions
+ **********************************************************************************************************************/
+
+/*******************************************************************************************************************//**
+ * Configure an IRQ input pin for use with the external interrupt interface. Implements @ref external_irq_api_t::open.
+ *
+ * The Open function is responsible for preparing an external IRQ pin for operation.
+ *
+ * @retval FSP_SUCCESS Open successful.
+ * @retval FSP_ERR_ASSERTION One of the following is invalid:
+ * - p_ctrl or p_cfg is NULL
+ * @retval FSP_ERR_ALREADY_OPEN The channel specified has already been opened. No configurations were changed.
+ * Call the associated Close function to reconfigure the channel.
+ * @retval FSP_ERR_IP_CHANNEL_NOT_PRESENT The channel requested in p_cfg is not available on the device selected in
+ * r_bsp_cfg.h.
+ * @retval FSP_ERR_INVALID_ARGUMENT p_cfg->p_callback is not NULL, but ISR is not enabled. ISR must be enabled to
+ * use callback function.
+ * @retval FSP_ERR_UNSUPPORTED An input argument is not supported by selected mode.
+ *
+ * @note This function is reentrant for different channels. It is not reentrant for the same channel.
+ **********************************************************************************************************************/
+fsp_err_t R_ICU_ExternalIrqOpen (external_irq_ctrl_t * const p_api_ctrl, external_irq_cfg_t const * const p_cfg)
+{
+ icu_instance_ctrl_t * p_ctrl = (icu_instance_ctrl_t *) p_api_ctrl;
+
+#if ICU_CFG_PARAM_CHECKING_ENABLE
+ FSP_ASSERT(NULL != p_ctrl);
+ FSP_ERROR_RETURN(ICU_OPEN != p_ctrl->open, FSP_ERR_ALREADY_OPEN);
+
+ FSP_ASSERT(NULL != p_cfg);
+
+ #if BSP_FEATURE_ICU_HAS_LOCO_FILTER
+ FSP_ASSERT(NULL != p_cfg->p_extend);
+ #endif
+
+ #if !BSP_FEATURE_ICU_HAS_FILTER
+
+ /* Verify the configuration trigger source is correct */
+ FSP_ERROR_RETURN((EXTERNAL_IRQ_TRIG_FALLING == p_cfg->trigger) ||
+ (EXTERNAL_IRQ_TRIG_RISING == p_cfg->trigger) ||
+ (EXTERNAL_IRQ_TRIG_BOTH_EDGE == p_cfg->trigger) ||
+ (EXTERNAL_IRQ_TRIG_LEVEL_LOW == p_cfg->trigger),
+ FSP_ERR_UNSUPPORTED);
+ #endif
+
+ FSP_ERROR_RETURN(0 != ((1ULL << p_cfg->channel) & BSP_FEATURE_ICU_IRQ_CHANNELS_MASK),
+ FSP_ERR_IP_CHANNEL_NOT_PRESENT);
+
+ /* Callback must be used with a valid interrupt priority otherwise it will never be called. */
+ if (p_cfg->p_callback)
+ {
+ FSP_ERROR_RETURN(BSP_IRQ_DISABLED != p_cfg->ipl, FSP_ERR_INVALID_ARGUMENT);
+ }
+#endif
+
+ p_ctrl->irq = p_cfg->irq;
+
+#if BSP_FEATURE_ICU_HAS_IELSR
+
+ /* IELSR Must be zero when modifying the IRQCR bits.
+ * (See "IRQ Control Register i (IRQCRi) (i = 0 to 15)" description in the ICU section of the relevant hardware manual). */
+ uint32_t ielsr = R_ICU->IELSR[p_ctrl->irq];
+ R_ICU->IELSR[p_ctrl->irq] = 0;
+#endif
+
+#if BSP_TZ_SECURE_BUILD
+
+ /* If this is a secure build, the callback provided in p_cfg must be secure. */
+ p_ctrl->p_callback_memory = NULL;
+#endif
+
+ /* Initialize control block. */
+ p_ctrl->p_callback = p_cfg->p_callback;
+ p_ctrl->p_context = p_cfg->p_context;
+ p_ctrl->channel = p_cfg->channel;
+
+ uint8_t channel = ICU_IRQCR_CH(p_ctrl->channel);
+ uint8_t irqcr = 0;
+
+#if BSP_FEATURE_ICU_HAS_FILTER
+
+ /* Disable digital filter */
+ ICU_IRQCR_REG[channel] = 0U;
+
+ #if BSP_FEATURE_ICU_HAS_LOCO_FILTER
+ icu_extended_cfg_t * p_extend = (icu_extended_cfg_t *) p_cfg->p_extend;
+
+ /* Set the digital filter divider. */
+ irqcr = (uint8_t) (p_extend->filter_src << R_ICU_IRQCR_LOCOSEL_Pos);
+ #endif
+
+ /* Set the digital filter divider. */
+ irqcr |= (uint8_t) (p_cfg->clock_source_div << ICU_FCLKSEL_OFFSET);
+
+ /* Enable/Disable digital filter. */
+ irqcr |= (uint8_t) (p_cfg->filter_enable << ICU_FLTEN_OFFSET);
+
+ /* Set the IRQ trigger. */
+ irqcr |= (uint8_t) (p_cfg->trigger << ICU_IRQMD_OFFSET);
+#else
+ irqcr = (uint8_t) (p_cfg->trigger << ICU_IRQMD_OFFSET);
+#endif
+
+ /* Write IRQCR */
+ ICU_IRQCR_REG[channel] = irqcr;
+
+#if BSP_FEATURE_ICU_HAS_IELSR
+ #if BSP_FEATURE_ICU_HAS_LOCO_FILTER
+
+ /* If LOCO is used as Digital Filtering Sample Clock, delay 4 LOCO clock cycles before restore IELSR */
+ if (EXTERNAL_IRQ_DIGITAL_FILTER_LOCO == p_extend->filter_src)
+ {
+ /* If LOCO is used as Digital Filtering Sample Clock, delay 4 LOCO clock cycles before restore IELSR.
+ * Total_cycles = (4 * system_clock_hz) / (loco_clock_hz).
+ */
+ uint32_t total_cycles = (uint32_t) ((4 * SYSTEM_CLOCK_HZ) / LOCO_CLOCK_HZ);
+
+ bsp_prv_software_delay_loop(BSP_DELAY_LOOPS_CALCULATE(total_cycles));
+ }
+ #endif
+
+ /* Restore IELSR. */
+ R_ICU->IELSR[p_ctrl->irq] = ielsr;
+#endif
+
+ /* NOTE: User can have the driver opened when the IRQ is not in the vector table. This is for use cases
+ * where the external IRQ driver is used to generate ELC events only (without CPU interrupts).
+ * In such cases we will not set the IRQ priority but will continue with the processing.
+ */
+ if (p_ctrl->irq >= 0)
+ {
+ R_BSP_IrqCfg(p_ctrl->irq, p_cfg->ipl, p_ctrl);
+ }
+
+ /* Mark the control block as open */
+ p_ctrl->open = ICU_OPEN;
+
+ return FSP_SUCCESS;
+}
+
+/*******************************************************************************************************************//**
+ * Enable external interrupt for specified channel at NVIC. Implements @ref external_irq_api_t::enable.
+ *
+ * @retval FSP_SUCCESS Interrupt Enabled successfully.
+ * @retval FSP_ERR_ASSERTION The p_ctrl parameter was null.
+ * @retval FSP_ERR_NOT_OPEN The channel is not opened.
+ * @retval FSP_ERR_IRQ_BSP_DISABLED Requested IRQ is not defined in this system
+ **********************************************************************************************************************/
+fsp_err_t R_ICU_ExternalIrqEnable (external_irq_ctrl_t * const p_api_ctrl)
+{
+ icu_instance_ctrl_t * p_ctrl = (icu_instance_ctrl_t *) p_api_ctrl;
+
+#if ICU_CFG_PARAM_CHECKING_ENABLE
+ FSP_ASSERT(NULL != p_ctrl);
+ FSP_ERROR_RETURN(ICU_OPEN == p_ctrl->open, FSP_ERR_NOT_OPEN);
+ FSP_ERROR_RETURN(p_ctrl->irq >= 0, FSP_ERR_IRQ_BSP_DISABLED);
+#endif
+
+ /* Clear the interrupt status and Pending bits, before the interrupt is enabled. */
+ R_BSP_IrqEnable(p_ctrl->irq);
+
+ return FSP_SUCCESS;
+}
+
+/*******************************************************************************************************************//**
+ * Disable external interrupt for specified channel at NVIC. Implements @ref external_irq_api_t::disable.
+ *
+ * @retval FSP_SUCCESS Interrupt disabled successfully.
+ * @retval FSP_ERR_ASSERTION The p_ctrl parameter was null.
+ * @retval FSP_ERR_NOT_OPEN The channel is not opened.
+ * @retval FSP_ERR_IRQ_BSP_DISABLED Requested IRQ is not defined in this system
+ **********************************************************************************************************************/
+fsp_err_t R_ICU_ExternalIrqDisable (external_irq_ctrl_t * const p_api_ctrl)
+{
+ icu_instance_ctrl_t * p_ctrl = (icu_instance_ctrl_t *) p_api_ctrl;
+
+#if ICU_CFG_PARAM_CHECKING_ENABLE
+ FSP_ASSERT(NULL != p_ctrl);
+ FSP_ERROR_RETURN(ICU_OPEN == p_ctrl->open, FSP_ERR_NOT_OPEN);
+ FSP_ERROR_RETURN(p_ctrl->irq >= 0, FSP_ERR_IRQ_BSP_DISABLED);
+#endif
+
+ /* Disable the interrupt, and then clear the interrupt pending bits and interrupt status. */
+ R_BSP_IrqDisable(p_ctrl->irq);
+
+ return FSP_SUCCESS;
+}
+
+/*******************************************************************************************************************//**
+ * Updates the user callback and has option of providing memory for callback structure.
+ * Implements external_irq_api_t::callbackSet
+ *
+ * @retval FSP_SUCCESS Callback updated successfully.
+ * @retval FSP_ERR_ASSERTION A required pointer is NULL.
+ * @retval FSP_ERR_NOT_OPEN The control block has not been opened.
+ * @retval FSP_ERR_NO_CALLBACK_MEMORY p_callback is non-secure and p_callback_memory is either secure or NULL.
+ **********************************************************************************************************************/
+fsp_err_t R_ICU_ExternalIrqCallbackSet (external_irq_ctrl_t * const p_api_ctrl,
+ void ( * p_callback)(
+ external_irq_callback_args_t *),
+ void * const p_context,
+ external_irq_callback_args_t * const p_callback_memory)
+{
+ icu_instance_ctrl_t * p_ctrl = p_api_ctrl;
+
+#if BSP_TZ_SECURE_BUILD
+
+ /* cmse_check_address_range returns NULL if p_callback is located in secure memory */
+ bool callback_is_secure =
+ (NULL == cmse_check_address_range((void *) p_callback, sizeof(void *), CMSE_AU_NONSECURE));
+#else
+ FSP_PARAMETER_NOT_USED(p_callback_memory);
+#endif
+
+#if ICU_CFG_PARAM_CHECKING_ENABLE
+ FSP_ASSERT(NULL != p_ctrl);
+ FSP_ERROR_RETURN(ICU_OPEN == p_ctrl->open, FSP_ERR_NOT_OPEN);
+ FSP_ASSERT(NULL != p_callback);
+
+ #if BSP_TZ_SECURE_BUILD
+
+ /* In secure projects, p_callback_memory must be provided in non-secure space if p_callback is non-secure */
+ external_irq_callback_args_t * const p_callback_memory_checked = cmse_check_pointed_object(p_callback_memory,
+ CMSE_AU_NONSECURE);
+ FSP_ERROR_RETURN(callback_is_secure || (NULL != p_callback_memory_checked), FSP_ERR_NO_CALLBACK_MEMORY);
+ #endif
+#endif
+
+#if BSP_TZ_SECURE_BUILD
+ p_ctrl->p_callback_memory = p_callback_memory;
+ p_ctrl->p_callback = callback_is_secure ? p_callback :
+ (void (*)(external_irq_callback_args_t *))cmse_nsfptr_create(p_callback);
+#else
+ p_ctrl->p_callback = p_callback;
+#endif
+ p_ctrl->p_context = p_context;
+
+ return FSP_SUCCESS;
+}
+
+/*******************************************************************************************************************//**
+ * Close the external interrupt channel. Implements @ref external_irq_api_t::close.
+ *
+ * @retval FSP_SUCCESS Successfully closed.
+ * @retval FSP_ERR_ASSERTION The parameter p_ctrl is NULL.
+ * @retval FSP_ERR_NOT_OPEN The channel is not opened.
+ **********************************************************************************************************************/
+fsp_err_t R_ICU_ExternalIrqClose (external_irq_ctrl_t * const p_api_ctrl)
+{
+ icu_instance_ctrl_t * p_ctrl = (icu_instance_ctrl_t *) p_api_ctrl;
+
+#if ICU_CFG_PARAM_CHECKING_ENABLE
+ FSP_ASSERT(NULL != p_ctrl);
+ FSP_ERROR_RETURN(ICU_OPEN == p_ctrl->open, FSP_ERR_NOT_OPEN);
+#endif
+
+ /* Cleanup. Disable interrupt */
+ if (p_ctrl->irq >= 0)
+ {
+ /* Disable the interrupt, and then clear the interrupt pending bits and interrupt status. */
+ R_BSP_IrqDisable(p_ctrl->irq);
+ R_FSP_IsrContextSet(p_ctrl->irq, NULL);
+ }
+
+ p_ctrl->open = 0U;
+
+ return FSP_SUCCESS;
+}
+
+/*******************************************************************************************************************//**
+ * @} (end addtogroup ICU)
+ **********************************************************************************************************************/
+
+/*******************************************************************************************************************//**
+ * ICU External Interrupt ISR.
+ **********************************************************************************************************************/
+void r_icu_isr (void)
+{
+ /* Save context if RTOS is used */
+ FSP_CONTEXT_SAVE
+
+ IRQn_Type irq = R_FSP_CurrentIrqGet();
+ icu_instance_ctrl_t * p_ctrl = (icu_instance_ctrl_t *) R_FSP_IsrContextGet(irq);
+
+#if BSP_FEATURE_ICU_HAS_IELSR
+ bool level_irq = false;
+
+ uint8_t channel = ICU_IRQCR_CH(p_ctrl->channel);
+ uint8_t mode = ICU_IRQCR_REG_BITFIELD[channel].IRQMD;
+
+ if (EXTERNAL_IRQ_TRIG_LEVEL_LOW == mode)
+ {
+ level_irq = true;
+ }
+ else
+ {
+ /* Clear the IR bit before calling the user callback so that if an edge is detected while the ISR is active
+ * it will not be missed. */
+ R_BSP_IrqStatusClear(irq);
+ }
+#endif
+
+ if ((NULL != p_ctrl) && (NULL != p_ctrl->p_callback))
+ {
+#if BSP_TZ_SECURE_BUILD
+
+ /* p_callback can point to a secure function or a non-secure function. */
+ external_irq_callback_args_t args;
+ if (!cmse_is_nsfptr(p_ctrl->p_callback))
+ {
+ /* If p_callback is secure, then the project does not need to change security state. */
+ args.channel = p_ctrl->channel;
+ args.p_context = p_ctrl->p_context;
+ p_ctrl->p_callback(&args);
+ }
+ else
+ {
+ /* Save current state of p_callback_args so that it can be shared between interrupts. */
+ args = *p_ctrl->p_callback_memory;
+
+ /* Set the callback args passed to the Non-secure callback. */
+ p_ctrl->p_callback_memory->channel = p_ctrl->channel;
+ p_ctrl->p_callback_memory->p_context = p_ctrl->p_context;
+
+ /* If p_callback is Non-secure, then the project must change to Non-secure state in order to call the callback. */
+ icu_prv_ns_callback p_callback = (icu_prv_ns_callback) (p_ctrl->p_callback);
+ p_callback(p_ctrl->p_callback_memory);
+
+ /* Restore the state of p_callback_args. */
+ *p_ctrl->p_callback_memory = args;
+ }
+
+#else
+
+ /* Set data to identify callback to user, then call user callback. */
+ external_irq_callback_args_t args;
+ args.channel = p_ctrl->channel;
+ args.p_context = p_ctrl->p_context;
+ p_ctrl->p_callback(&args);
+#endif
+ }
+
+#if BSP_FEATURE_ICU_HAS_IELSR
+ if (level_irq)
+ {
+ /* Clear the IR bit after calling the user callback so that if the condition is cleared the ISR will not
+ * be called again. */
+ R_BSP_IrqStatusClear(irq);
+ }
+#endif
+
+ /* Restore context if RTOS is used */
+ FSP_CONTEXT_RESTORE
+}
diff --git a/bsp/renesas/ra8p1-titan-board/m85/ra_cfg/fsp_cfg/bsp/bsp_mcu_family_cfg.h b/bsp/renesas/ra8p1-titan-board/m85/ra_cfg/fsp_cfg/bsp/bsp_mcu_family_cfg.h
index f47130bd7a..fe53256109 100644
--- a/bsp/renesas/ra8p1-titan-board/m85/ra_cfg/fsp_cfg/bsp/bsp_mcu_family_cfg.h
+++ b/bsp/renesas/ra8p1-titan-board/m85/ra_cfg/fsp_cfg/bsp/bsp_mcu_family_cfg.h
@@ -280,7 +280,7 @@
(((RA_NOT_DEFINED > 0) ? 0U : 1U) << 17U) /* External IRQ17 */ | \
(((RA_NOT_DEFINED > 0) ? 0U : 1U) << 18U) /* External IRQ18 */ | \
(((RA_NOT_DEFINED > 0) ? 0U : 1U) << 19U) /* External IRQ19 */ | \
- (((RA_NOT_DEFINED > 0) ? 0U : 1U) << 20U) /* External IRQ20 */ | \
+ (((1 > 0) ? 0U : 1U) << 20U) /* External IRQ20 */ | \
(((RA_NOT_DEFINED > 0) ? 0U : 1U) << 21U) /* External IRQ21 */ | \
(((RA_NOT_DEFINED > 0) ? 0U : 1U) << 22U) /* External IRQ22 */ | \
(((RA_NOT_DEFINED > 0) ? 0U : 1U) << 23U) /* External IRQ23 */ | \
diff --git a/bsp/renesas/ra8p1-titan-board/m85/ra_cfg/fsp_cfg/r_icu_cfg.h b/bsp/renesas/ra8p1-titan-board/m85/ra_cfg/fsp_cfg/r_icu_cfg.h
new file mode 100644
index 0000000000..85fb06ed55
--- /dev/null
+++ b/bsp/renesas/ra8p1-titan-board/m85/ra_cfg/fsp_cfg/r_icu_cfg.h
@@ -0,0 +1,13 @@
+/* generated configuration header file - do not edit */
+#ifndef R_ICU_CFG_H_
+#define R_ICU_CFG_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ICU_CFG_PARAM_CHECKING_ENABLE (BSP_CFG_PARAM_CHECKING_ENABLE)
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* R_ICU_CFG_H_ */
diff --git a/bsp/renesas/ra8p1-titan-board/m85/ra_gen/common_data.c b/bsp/renesas/ra8p1-titan-board/m85/ra_gen/common_data.c
index e0fe8de179..9509842406 100644
--- a/bsp/renesas/ra8p1-titan-board/m85/ra_gen/common_data.c
+++ b/bsp/renesas/ra8p1-titan-board/m85/ra_gen/common_data.c
@@ -1,6 +1,42 @@
/* generated common source file - do not edit */
#include "common_data.h"
+icu_instance_ctrl_t g_external_irq20_ctrl;
+
+/** External IRQ extended configuration for ICU HAL driver */
+const icu_extended_cfg_t g_external_irq20_ext_cfg =
+{
+ .filter_src = EXTERNAL_IRQ_DIGITAL_FILTER_PCLK_DIV,
+};
+
+const external_irq_cfg_t g_external_irq20_cfg =
+{
+ .channel = 20,
+ .trigger = EXTERNAL_IRQ_TRIG_FALLING,
+ .filter_enable = false,
+ .clock_source_div = EXTERNAL_IRQ_CLOCK_SOURCE_DIV_64,
+ .p_callback = irq_callback,
+ /** If NULL then do not add & */
+#if defined(NULL)
+ .p_context = NULL,
+#else
+ .p_context = (void *) &NULL,
+#endif
+ .p_extend = (void *)&g_external_irq20_ext_cfg,
+ .ipl = (12),
+#if defined(VECTOR_NUMBER_ICU_IRQ20)
+ .irq = VECTOR_NUMBER_ICU_IRQ20,
+#else
+ .irq = FSP_INVALID_VECTOR,
+#endif
+};
+/* Instance structure to use this module. */
+const external_irq_instance_t g_external_irq20 =
+{
+ .p_ctrl = &g_external_irq20_ctrl,
+ .p_cfg = &g_external_irq20_cfg,
+ .p_api = &g_external_irq_on_icu
+};
const ether_phy_lsi_cfg_t g_rmac_phy_lsi1 =
{
.address = 1,
diff --git a/bsp/renesas/ra8p1-titan-board/m85/ra_gen/common_data.h b/bsp/renesas/ra8p1-titan-board/m85/ra_gen/common_data.h
index 4c9ad485e7..be8f18513f 100644
--- a/bsp/renesas/ra8p1-titan-board/m85/ra_gen/common_data.h
+++ b/bsp/renesas/ra8p1-titan-board/m85/ra_gen/common_data.h
@@ -3,12 +3,24 @@
#define COMMON_DATA_H_
#include <stdint.h>
#include "bsp_api.h"
+#include "r_icu.h"
+#include "r_external_irq_api.h"
#include "r_rmac_phy.h"
#include "r_ether_phy_api.h"
#include "r_layer3_switch.h"
#include "r_ioport.h"
#include "bsp_pin_cfg.h"
FSP_HEADER
+/** External IRQ on ICU Instance. */
+extern const external_irq_instance_t g_external_irq20;
+
+/** Access the ICU instance using these structures when calling API functions directly (::p_api is not used). */
+extern icu_instance_ctrl_t g_external_irq20_ctrl;
+extern const external_irq_cfg_t g_external_irq20_cfg;
+
+#ifndef irq_callback
+void irq_callback(external_irq_callback_args_t * p_args);
+#endif
#ifndef ETHER_PHY_LSI_TYPE_KIT_COMPONENT
#define ETHER_PHY_LSI_TYPE_KIT_COMPONENT ETHER_PHY_LSI_TYPE_DEFAULT
#endif
diff --git a/bsp/renesas/ra8p1-titan-board/m85/ra_gen/pin_data.c b/bsp/renesas/ra8p1-titan-board/m85/ra_gen/pin_data.c
index 8b31d7dd2d..29ee4f10b4 100644
--- a/bsp/renesas/ra8p1-titan-board/m85/ra_gen/pin_data.c
+++ b/bsp/renesas/ra8p1-titan-board/m85/ra_gen/pin_data.c
@@ -61,7 +61,12 @@ const ioport_pin_cfg_t g_bsp_pin_cfg_data[] = {
.pin = BSP_IO_PORT_01_PIN_09,
.pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_GPT1)
},
-
+
+ {
+ .pin = BSP_IO_PORT_01_PIN_10,
+ .pin_cfg = ((uint32_t) IOPORT_CFG_IRQ_ENABLE | (uint32_t) IOPORT_CFG_PORT_DIRECTION_INPUT)
+ },
+
{
.pin = BSP_IO_PORT_01_PIN_11,
.pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_SDHI_MMC)
diff --git a/bsp/renesas/ra8p1-titan-board/m85/ra_gen/vector_data.c b/bsp/renesas/ra8p1-titan-board/m85/ra_gen/vector_data.c
index 15826b8bde..735fd9e009 100644
--- a/bsp/renesas/ra8p1-titan-board/m85/ra_gen/vector_data.c
+++ b/bsp/renesas/ra8p1-titan-board/m85/ra_gen/vector_data.c
@@ -53,6 +53,7 @@
[46] = sci_b_uart_txi_isr, /* SCI0 TXI (Transmit data empty) */
[47] = sci_b_uart_tei_isr, /* SCI0 TEI (Transmit end) */
[48] = sci_b_uart_eri_isr, /* SCI0 ERI (Receive error) */
+ [49] = r_icu_isr, /* ICU IRQ20 (External pin interrupt 20) */
};
#if BSP_FEATURE_ICU_HAS_IELSR
const bsp_interrupt_event_t g_interrupt_event_link_select[BSP_ICU_VECTOR_NUM_ENTRIES] =
@@ -106,6 +107,7 @@
[46] = BSP_PRV_VECT_ENUM(EVENT_SCI0_TXI,FIXED), /* SCI0 TXI (Transmit data empty) */
[47] = BSP_PRV_VECT_ENUM(EVENT_SCI0_TEI,FIXED), /* SCI0 TEI (Transmit end) */
[48] = BSP_PRV_VECT_ENUM(EVENT_SCI0_ERI,FIXED), /* SCI0 ERI (Receive error) */
+ [49] = BSP_PRV_VECT_ENUM(EVENT_ICU_IRQ20,FIXED), /* ICU IRQ20 (External pin interrupt 20) */
};
#endif
#endif \ No newline at end of file
diff --git a/bsp/renesas/ra8p1-titan-board/m85/ra_gen/vector_data.h b/bsp/renesas/ra8p1-titan-board/m85/ra_gen/vector_data.h
index 06ecacfb50..ea7742d84e 100644
--- a/bsp/renesas/ra8p1-titan-board/m85/ra_gen/vector_data.h
+++ b/bsp/renesas/ra8p1-titan-board/m85/ra_gen/vector_data.h
@@ -6,7 +6,7 @@
#endif
/* Number of interrupts allocated */
#ifndef VECTOR_DATA_IRQ_COUNT
- #define VECTOR_DATA_IRQ_COUNT (49)
+ #define VECTOR_DATA_IRQ_COUNT (50)
#endif
/* ISR prototypes */
void sci_b_uart_rxi_isr(void);
@@ -51,6 +51,7 @@
void spi_b_txi_isr(void);
void spi_b_tei_isr(void);
void spi_b_eri_isr(void);
+ void r_icu_isr(void);
/* Vector table allocations */
#define VECTOR_NUMBER_SCI8_RXI ((IRQn_Type) 0) /* SCI8 RXI (Receive data full) */
@@ -151,8 +152,10 @@
#define SCI0_TEI_IRQn ((IRQn_Type) 47) /* SCI0 TEI (Transmit end) */
#define VECTOR_NUMBER_SCI0_ERI ((IRQn_Type) 48) /* SCI0 ERI (Receive error) */
#define SCI0_ERI_IRQn ((IRQn_Type) 48) /* SCI0 ERI (Receive error) */
+ #define VECTOR_NUMBER_ICU_IRQ20 ((IRQn_Type) 49) /* ICU IRQ20 (External pin interrupt 20) */
+ #define ICU_IRQ20_IRQn ((IRQn_Type) 49) /* ICU IRQ20 (External pin interrupt 20) */
/* The number of entries required for the ICU vector table. */
- #define BSP_ICU_VECTOR_NUM_ENTRIES (49)
+ #define BSP_ICU_VECTOR_NUM_ENTRIES (50)
#ifdef __cplusplus
}
diff --git a/bsp/renesas/ra8p1-titan-board/m85/rtconfig.py b/bsp/renesas/ra8p1-titan-board/m85/rtconfig.py
index b890016b82..6f58c28b0d 100644
--- a/bsp/renesas/ra8p1-titan-board/m85/rtconfig.py
+++ b/bsp/renesas/ra8p1-titan-board/m85/rtconfig.py
@@ -36,6 +36,7 @@ if PLATFORM == 'gcc':
AS = PREFIX + 'gcc'
AR = PREFIX + 'ar'
CXX = PREFIX + 'g++'
+ CPP = PREFIX + 'gcc'
LINK = PREFIX + 'gcc'
TARGET_EXT = 'elf'
SIZE = PREFIX + 'size'
@@ -46,6 +47,7 @@ if PLATFORM == 'gcc':
DEVICE = ' -march=armv8.1-m.main+mve.fp+fp.dp -mthumb -mfpu=fpv5-sp-d16 -mfloat-abi=hard -ffunction-sections -fdata-sections'
CFLAGS = DEVICE + ' -Dgcc'
AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp -Wa,-mimplicit-it=thumb '
+ CPPFLAGS = ' -E -P -x assembler-with-cpp'
LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,Reset_Handler -T script/fsp.ld -L script/'
CPATH = ''
diff --git a/bsp/renesas/ra8p1-titan-board/m85/script/fsp.ld b/bsp/renesas/ra8p1-titan-board/m85/script/fsp.ld
index 1d69809f7c..95427804f1 100644
--- a/bsp/renesas/ra8p1-titan-board/m85/script/fsp.ld
+++ b/bsp/renesas/ra8p1-titan-board/m85/script/fsp.ld
@@ -89,7 +89,7 @@ SECTIONS
/***** OSPI0_CS1 memory section allocations ******/
- .ospi0_cs1.startof (READONLY) :
+ .ospi0_cs1.startof :
{
__ddsc_OSPI0_CS1_START = .;
@@ -204,7 +204,7 @@ SECTIONS
__ram_from_ospi0_cs1$$Limit = .;
}> RAM AT > OSPI0_CS1
- __ospi0_cs1_readonly$$ (READONLY) :
+ __ospi0_cs1_readonly$$ :
{
__ospi0_cs1_readonly$$Base = .;
/* section.ospi0_cs1.readonly */
@@ -220,14 +220,14 @@ SECTIONS
*(.ospi0_cs1_noinit)
__ospi0_cs1_noinit$$Limit = .;
}> OSPI0_CS1
- .ospi0_cs1.endof ALIGN(.,512) (READONLY) :
+ .ospi0_cs1.endof ALIGN(.,512) :
{
__ddsc_OSPI0_CS1_END = .;
}> OSPI0_CS1
/***** OSPI1_CS1 memory section allocations ******/
- .ospi1_cs1.startof (READONLY) :
+ .ospi1_cs1.startof :
{
__ddsc_OSPI1_CS1_START = .;
@@ -306,7 +306,7 @@ SECTIONS
__ram_from_ospi1_cs1$$Limit = .;
}> RAM AT > OSPI1_CS1
- __ospi1_cs1_readonly$$ (READONLY) :
+ __ospi1_cs1_readonly$$ :
{
__ospi1_cs1_readonly$$Base = .;
/* section.ospi1_cs1.readonly */
@@ -322,14 +322,14 @@ SECTIONS
*(.ospi1_cs1_noinit)
__ospi1_cs1_noinit$$Limit = .;
}> OSPI1_CS1
- .ospi1_cs1.endof ALIGN(.,512) (READONLY) :
+ .ospi1_cs1.endof ALIGN(.,512) :
{
__ddsc_OSPI1_CS1_END = .;
}> OSPI1_CS1
/***** DATA_FLASH memory section allocations ******/
- .data_flash.startof (READONLY) :
+ .data_flash.startof :
{
__ddsc_DATA_FLASH_START = .;
@@ -408,7 +408,7 @@ SECTIONS
__ram_from_data_flash$$Limit = .;
}> RAM AT > DATA_FLASH
- __data_flash_readonly$$ (READONLY) :
+ __data_flash_readonly$$ :
{
__data_flash_readonly$$Base = .;
/* section.data_flash.readonly */
@@ -424,20 +424,20 @@ SECTIONS
*(.data_flash_noinit)
__data_flash_noinit$$Limit = .;
}> DATA_FLASH
- .data_flash.endof ALIGN(.,1024) (READONLY) :
+ .data_flash.endof ALIGN(.,1024) :
{
__ddsc_DATA_FLASH_END = .;
}> DATA_FLASH
/***** FLASH memory section allocations ******/
- .flash.startof (READONLY) :
+ .flash.startof :
{
__ddsc_FLASH_START = .;
}> FLASH
/* MCU vector table */
- __flash_vectors$$ (READONLY) :
+ __flash_vectors$$ :
{
__flash_vectors$$Base = .; _VECTORS = .;
KEEP(*(.fixed_vectors))
@@ -771,7 +771,7 @@ SECTIONS
at run time for things such as ThreadX memory pool allocations. */
__RAM_segment_used_end__ = ALIGN(__sau_ddsc_RAM_NSC , 4);
- __flash_readonly$$ (READONLY) :
+ __flash_readonly$$ :
{
__flash_readonly$$Base = .;
/* section.flash.readonly */
@@ -784,7 +784,7 @@ SECTIONS
KEEP(*(.version))
__flash_readonly$$Limit = .;
}> FLASH
- __flash_ctor$$ (READONLY) :
+ __flash_ctor$$ :
{
*crtbegin.o(.ctors)
@@ -799,27 +799,27 @@ SECTIONS
*(.dtors)
}> FLASH
- __flash_preinit_array$$ (READONLY) : ALIGN(4)
+ __flash_preinit_array$$ : ALIGN(4)
{
__preinit_array_start = .;
KEEP(*(.preinit_array))
__preinit_array_end = .;
}> FLASH
- __flash_.got$$ (READONLY) :
+ __flash_.got$$ :
{
*(.got.plt)
*(.got)
}> FLASH
- __flash_init_array$$ (READONLY) : ALIGN(4)
+ __flash_init_array$$ : ALIGN(4)
{
__init_array_start = .;
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
__init_array_end = .;
}> FLASH
- __flash_fini_array$$ (READONLY) : ALIGN(4)
+ __flash_fini_array$$ : ALIGN(4)
{
__fini_array_start = .;
KEEP(*(SORT(.fini_array.*)))
@@ -827,7 +827,7 @@ SECTIONS
__fini_array_end = .;
}> FLASH
/* Discard exception tables */
- /DISCARD/ (READONLY) :
+ /DISCARD/ :
{
*(.ARM.extab*)
@@ -837,264 +837,264 @@ SECTIONS
}> FLASH
/* Dummy section to hold required exidx labels */
- __flash_arm.exidx$$ (READONLY) :
+ __flash_arm.exidx$$ :
{
__exidx_start = .;
__exidx_end = .;
}> FLASH
- .flash.endof ALIGN(.,32768) (READONLY) :
+ .flash.endof ALIGN(.,32768) :
{
__ddsc_FLASH_END = .;
}> FLASH
- .flash.flat_nsc (READONLY) :
+ .flash.flat_nsc :
{
__sau_ddsc_FLASH_NSC = .;
}> FLASH
/***** OPTION_SETTING_OFS0 memory section allocations ******/
- .option_setting_ofs0.startof (READONLY) :
+ .option_setting_ofs0.startof :
{
__ddsc_OPTION_SETTING_OFS0_START = .;
}> OPTION_SETTING_OFS0
/* Option Function Select Register 0 */
- __option_setting_ofs0_reg$$ (READONLY) :
+ __option_setting_ofs0_reg$$ :
{
__option_setting_ofs0_reg$$Base = .;
KEEP(*(.option_setting_ofs0))
__option_setting_ofs0_reg$$Limit = .;
}> OPTION_SETTING_OFS0
- .option_setting_ofs0.endof (READONLY) :
+ .option_setting_ofs0.endof :
{
__ddsc_OPTION_SETTING_OFS0_END = .;
}> OPTION_SETTING_OFS0
/***** OPTION_SETTING_OFS2 memory section allocations ******/
- .option_setting_ofs2.startof (READONLY) :
+ .option_setting_ofs2.startof :
{
__ddsc_OPTION_SETTING_OFS2_START = .;
}> OPTION_SETTING_OFS2
/* Option Function Select Register 2 */
- __option_setting_ofs2_reg$$ (READONLY) :
+ __option_setting_ofs2_reg$$ :
{
__option_setting_ofs2_reg$$Base = .;
KEEP(*(.option_setting_ofs2))
__option_setting_ofs2_reg$$Limit = .;
}> OPTION_SETTING_OFS2
- .option_setting_ofs2.endof (READONLY) :
+ .option_setting_ofs2.endof :
{
__ddsc_OPTION_SETTING_OFS2_END = .;
}> OPTION_SETTING_OFS2
/***** OPTION_SETTING_SAS memory section allocations ******/
- .option_setting_sas.startof (READONLY) :
+ .option_setting_sas.startof :
{
__ddsc_OPTION_SETTING_SAS_START = .;
}> OPTION_SETTING_SAS
/* Startup Area Setting Register */
- __option_setting_sas_reg$$ (READONLY) :
+ __option_setting_sas_reg$$ :
{
__option_setting_sas_reg$$Base = .;
KEEP(*(.option_setting_sas))
__option_setting_sas_reg$$Limit = .;
}> OPTION_SETTING_SAS
- .option_setting_sas.endof (READONLY) :
+ .option_setting_sas.endof :
{
__ddsc_OPTION_SETTING_SAS_END = .;
}> OPTION_SETTING_SAS
/***** OPTION_SETTING_OFS1 memory section allocations ******/
- .option_setting_ofs1.startof (READONLY) :
+ .option_setting_ofs1.startof :
{
__ddsc_OPTION_SETTING_OFS1_START = .;
}> OPTION_SETTING_OFS1
/* Option Function Select Register 1 */
- __option_setting_ofs1_reg$$ (READONLY) :
+ __option_setting_ofs1_reg$$ :
{
__option_setting_ofs1_reg$$Base = .;
KEEP(*(.option_setting_ofs1))
__option_setting_ofs1_reg$$Limit = .;
}> OPTION_SETTING_OFS1
- .option_setting_ofs1.endof (READONLY) :
+ .option_setting_ofs1.endof :
{
__ddsc_OPTION_SETTING_OFS1_END = .;
}> OPTION_SETTING_OFS1
/***** OPTION_SETTING_OFS1_SEC memory section allocations ******/
- .option_setting_ofs1_sec.startof (READONLY) :
+ .option_setting_ofs1_sec.startof :
{
__ddsc_OPTION_SETTING_OFS1_SEC_START = .;
}> OPTION_SETTING_OFS1_SEC
/* Option Function Select Register 1 Secure */
- __option_setting_ofs1_sec_reg$$ (READONLY) :
+ __option_setting_ofs1_sec_reg$$ :
{
__option_setting_ofs1_sec_reg$$Base = .;
KEEP(*(.option_setting_ofs1_sec))
__option_setting_ofs1_sec_reg$$Limit = .;
}> OPTION_SETTING_OFS1_SEC
- .option_setting_ofs1_sec.endof (READONLY) :
+ .option_setting_ofs1_sec.endof :
{
__ddsc_OPTION_SETTING_OFS1_SEC_END = .;
}> OPTION_SETTING_OFS1_SEC
/***** OPTION_SETTING_OFS1_SEL memory section allocations ******/
- .option_setting_ofs1_sel.startof (READONLY) :
+ .option_setting_ofs1_sel.startof :
{
__ddsc_OPTION_SETTING_OFS1_SEL_START = .;
}> OPTION_SETTING_OFS1_SEL
/* OFS1 Register Select */
- __option_setting_ofs1_sel_reg$$ (READONLY) :
+ __option_setting_ofs1_sel_reg$$ :
{
__option_setting_ofs1_sel_reg$$Base = .;
KEEP(*(.option_setting_ofs1_sel))
__option_setting_ofs1_sel_reg$$Limit = .;
}> OPTION_SETTING_OFS1_SEL
- .option_setting_ofs1_sel.endof (READONLY) :
+ .option_setting_ofs1_sel.endof :
{
__ddsc_OPTION_SETTING_OFS1_SEL_END = .;
}> OPTION_SETTING_OFS1_SEL
/***** OPTION_SETTING_OFS3 memory section allocations ******/
- .option_setting_ofs3.startof (READONLY) :
+ .option_setting_ofs3.startof :
{
__ddsc_OPTION_SETTING_OFS3_START = .;
}> OPTION_SETTING_OFS3
/* Option Function Select Register 3 */
- __option_setting_ofs3_reg$$ (READONLY) :
+ __option_setting_ofs3_reg$$ :
{
__option_setting_ofs3_reg$$Base = .;
KEEP(*(.option_setting_ofs3))
__option_setting_ofs3_reg$$Limit = .;
}> OPTION_SETTING_OFS3
- .option_setting_ofs3.endof (READONLY) :
+ .option_setting_ofs3.endof :
{
__ddsc_OPTION_SETTING_OFS3_END = .;
}> OPTION_SETTING_OFS3
/***** OPTION_SETTING_OFS3_SEC memory section allocations ******/
- .option_setting_ofs3_sec.startof (READONLY) :
+ .option_setting_ofs3_sec.startof :
{
__ddsc_OPTION_SETTING_OFS3_SEC_START = .;
}> OPTION_SETTING_OFS3_SEC
/* Option Function Select Register 3 Secure */
- __option_setting_ofs3_sec_reg$$ (READONLY) :
+ __option_setting_ofs3_sec_reg$$ :
{
__option_setting_ofs3_sec_reg$$Base = .;
KEEP(*(.option_setting_ofs3_sec))
__option_setting_ofs3_sec_reg$$Limit = .;
}> OPTION_SETTING_OFS3_SEC
- .option_setting_ofs3_sec.endof (READONLY) :
+ .option_setting_ofs3_sec.endof :
{
__ddsc_OPTION_SETTING_OFS3_SEC_END = .;
}> OPTION_SETTING_OFS3_SEC
/***** OPTION_SETTING_OFS3_SEL memory section allocations ******/
- .option_setting_ofs3_sel.startof (READONLY) :
+ .option_setting_ofs3_sel.startof :
{
__ddsc_OPTION_SETTING_OFS3_SEL_START = .;
}> OPTION_SETTING_OFS3_SEL
/* OFS3 Register Select */
- __option_setting_ofs3_sel_reg$$ (READONLY) :
+ __option_setting_ofs3_sel_reg$$ :
{
__option_setting_ofs3_sel_reg$$Base = .;
KEEP(*(.option_setting_ofs3_sel))
__option_setting_ofs3_sel_reg$$Limit = .;
}> OPTION_SETTING_OFS3_SEL
- .option_setting_ofs3_sel.endof (READONLY) :
+ .option_setting_ofs3_sel.endof :
{
__ddsc_OPTION_SETTING_OFS3_SEL_END = .;
}> OPTION_SETTING_OFS3_SEL
/***** OPTION_SETTING_BPS memory section allocations ******/
- .option_setting_bps.startof (READONLY) :
+ .option_setting_bps.startof :
{
__ddsc_OPTION_SETTING_BPS_START = .;
}> OPTION_SETTING_BPS
/* Block Protect Setting Register */
- __option_setting_bps_reg$$ (READONLY) :
+ __option_setting_bps_reg$$ :
{
__option_setting_bps_reg$$Base = .;
KEEP(*(.option_setting_bps))
__option_setting_bps_reg$$Limit = .;
}> OPTION_SETTING_BPS
- .option_setting_bps.endof (READONLY) :
+ .option_setting_bps.endof :
{
__ddsc_OPTION_SETTING_BPS_END = .;
}> OPTION_SETTING_BPS
/***** OPTION_SETTING_BPS_SEC memory section allocations ******/
- .option_setting_bps_sec.startof (READONLY) :
+ .option_setting_bps_sec.startof :
{
__ddsc_OPTION_SETTING_BPS_SEC_START = .;
}> OPTION_SETTING_BPS_SEC
/* Block Protect Setting Register Secure */
- __option_setting_bps_sec_reg$$ (READONLY) :
+ __option_setting_bps_sec_reg$$ :
{
__option_setting_bps_sec_reg$$Base = .;
KEEP(*(.option_setting_bps_sec))
__option_setting_bps_sec_reg$$Limit = .;
}> OPTION_SETTING_BPS_SEC
- .option_setting_bps_sec.endof (READONLY) :
+ .option_setting_bps_sec.endof :
{
__ddsc_OPTION_SETTING_BPS_SEC_END = .;
}> OPTION_SETTING_BPS_SEC
/***** OPTION_SETTING_OTP_PBPS_SEC memory section allocations ******/
- .option_setting_otp_pbps_sec.startof (READONLY) :
+ .option_setting_otp_pbps_sec.startof :
{
__ddsc_OPTION_SETTING_OTP_PBPS_SEC_START = .;
}> OPTION_SETTING_OTP_PBPS_SEC
/* Permanent Block Protect Setting Register Secure */
- __option_setting_otp_pbps_sec_reg$$ (READONLY) :
+ __option_setting_otp_pbps_sec_reg$$ :
{
__option_setting_otp_pbps_sec_reg$$Base = .;
KEEP(*(.option_setting_otp_pbps_sec))
__option_setting_otp_pbps_sec_reg$$Limit = .;
}> OPTION_SETTING_OTP_PBPS_SEC
- .option_setting_otp_pbps_sec.endof (READONLY) :
+ .option_setting_otp_pbps_sec.endof :
{
__ddsc_OPTION_SETTING_OTP_PBPS_SEC_END = .;
}> OPTION_SETTING_OTP_PBPS_SEC
/***** OPTION_SETTING_OTP_PBPS memory section allocations ******/
- .option_setting_otp_pbps.startof (READONLY) :
+ .option_setting_otp_pbps.startof :
{
__ddsc_OPTION_SETTING_OTP_PBPS_START = .;
}> OPTION_SETTING_OTP_PBPS
/* Permanent Block Protect Setting Register */
- __option_setting_otp_pbps_reg$$ (READONLY) :
+ __option_setting_otp_pbps_reg$$ :
{
__option_setting_otp_pbps_reg$$Base = .;
KEEP(*(.option_setting_otp_pbps))
__option_setting_otp_pbps_reg$$Limit = .;
}> OPTION_SETTING_OTP_PBPS
- .option_setting_otp_pbps.endof (READONLY) :
+ .option_setting_otp_pbps.endof :
{
__ddsc_OPTION_SETTING_OTP_PBPS_END = .;
diff --git a/bsp/renesas/ra8p1-titan-board/m85/src/hal_entry.c b/bsp/renesas/ra8p1-titan-board/m85/src/hal_entry.c
index c879f5f2b9..1373ccb4b2 100644
--- a/bsp/renesas/ra8p1-titan-board/m85/src/hal_entry.c
+++ b/bsp/renesas/ra8p1-titan-board/m85/src/hal_entry.c
@@ -13,7 +13,9 @@
#include <rtdevice.h>
#include <board.h>
+#ifndef RT_USING_DM
#define LED_PIN BSP_IO_PORT_00_PIN_12 /* Onboard LED pins */
+#endif
void hal_entry(void)
{
@@ -21,6 +23,7 @@ void hal_entry(void)
rt_kprintf("Hello, Titan Board!\n");
rt_kprintf("==================================================\n");
+#ifndef RT_USING_DM
rt_pin_mode(LED_PIN, PIN_MODE_OUTPUT);
while (1)
@@ -30,4 +33,10 @@ void hal_entry(void)
rt_pin_write(LED_PIN, PIN_LOW);
rt_thread_mdelay(1000);
}
+#else
+ while (1)
+ {
+ rt_thread_mdelay(1000);
+ }
+#endif
}