diff options
| author | Rbb666 <[email protected]> | 2026-07-31 15:23:24 +0800 |
|---|---|---|
| committer | Rbb666 <[email protected]> | 2026-08-12 12:54:50 +0800 |
| commit | abce28f15cc868f72d0d1f2bfc7e46343869e6d6 (patch) | |
| tree | a0a3515b469994332db81b65b7497a4ffe5f2d67 | |
| parent | 655aea948e8d1c5e77cd2a9b85cd45bf864df72d (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.
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  +### 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)  +### 启用设备模型(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 } |
