Skip to content

drivers: watchdog: Add watchdog driver support on Renesas RX130 #89914

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 78 additions & 3 deletions arch/rx/core/vects.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,18 @@
#include <zephyr/irq.h>
#include <kswap.h>
#include <zephyr/tracing/tracing.h>
#include <zephyr/arch/rx/sw_nmi_table.h>

typedef void (*fp)(void);
extern void _start(void);
extern void z_rx_irq_exit(void);
extern void R_BSP_SoftwareReset(void);

#define NMI_NMIST_MASK 0x01
#define NMI_OSTST_MASK 0x02
#define NMI_IWDTST_MASK 0x08
#define NMI_LVD1ST_MASK 0x10
#define NMI_LVD2ST_MASK 0x20

/* this is mainly to give Visual Studio Code peace of mind */
#ifndef CONFIG_GEN_IRQ_START_VECTOR
Expand Down Expand Up @@ -97,9 +105,9 @@ static void __ISR__ INT_Excep_FloatingPoint(void)
static void __ISR__ INT_NonMaskableInterrupt(void)
{
REGISTER_SAVE();
ISR_DIRECT_HEADER();
z_fatal_error(K_ERR_CPU_EXCEPTION, NULL);
ISR_DIRECT_FOOTER(1);
int nmi_vector = get_nmi_request();

handle_nmi(nmi_vector);
REGISTER_RESTORE_EXIT();
}

Expand Down Expand Up @@ -141,6 +149,64 @@ static void __ISR__ reserved_isr(void)
/* wrapper for z_rx_context_switch_isr, defined in switch.S */
extern void __ISR__ switch_isr_wrapper(void);

void nmi_enable(uint8_t nmi_vector, nmi_callback_t callback, void *arg)
{
if (nmi_vector >= NMI_TABLE_SIZE) {
return;
}

_nmi_vector_table[nmi_vector].callback = callback;
_nmi_vector_table[nmi_vector].arg = arg;
}

int get_nmi_request(void)
{
uint32_t nmi_status = ICU.NMISR.BYTE;

if (nmi_status & NMI_NMIST_MASK) {
return 0;
} else if (nmi_status & NMI_OSTST_MASK) {
return 1;
} else if (nmi_status & NMI_IWDTST_MASK) {
return 2;
} else if (nmi_status & NMI_LVD1ST_MASK) {
return 3;
} else if (nmi_status & NMI_LVD2ST_MASK) {
return 4;
}

return NMI_TABLE_SIZE;
}

void handle_nmi(uint8_t nmi_vector)
{
if (nmi_vector >= NMI_TABLE_SIZE) {
return;
}

_nmi_vector_table[nmi_vector].callback(_nmi_vector_table[nmi_vector].arg);

switch (nmi_vector) {
case 0:
ICU.NMICLR.BIT.NMICLR = 0x01;
break;
case 1:
ICU.NMICLR.BIT.OSTCLR = 0x01;
break;
case 2:
ICU.NMICLR.BIT.IWDTCLR = 0x01;
break;
case 3:
ICU.NMICLR.BIT.LVD1CLR = 0x01;
break;
case 4:
ICU.NMICLR.BIT.LVD2CLR = 0x01;
break;
default:
break;
}
}

/* this macro is used to define "demuxing" ISRs for all interrupts that are
* handled through Zephyr's software isr table.
*/
Expand Down Expand Up @@ -394,6 +460,15 @@ INT_DEMUX(253);
INT_DEMUX(254);
INT_DEMUX(255);

struct nmi_vector_entry _nmi_vector_table[NMI_TABLE_SIZE] = {
{(nmi_callback_t)0xFFFFFFFFU, (void *)0xFFFFFFFFU}, /* NMI Pin Interrupt */
{(nmi_callback_t)0xFFFFFFFFU,
(void *)0xFFFFFFFFU}, /* Oscillation Stop Detection Interrupt */
{(nmi_callback_t)0xFFFFFFFFU, (void *)0xFFFFFFFFU}, /* IWDT Underflow/Refresh Error */
{(nmi_callback_t)0xFFFFFFFFU, (void *)0xFFFFFFFFU}, /* Voltage Monitoring 1 Interrupt */
{(nmi_callback_t)0xFFFFFFFFU, (void *)0xFFFFFFFFU}, /* Voltage Monitoring 2 Interrupt */
};

const void *FixedVectors[] FVECT_SECT = {
/* 0x00-0x4c: Reserved, must be 0xff (according to e2 studio example) */
/* Reserved for OFSM */
Expand Down
11 changes: 11 additions & 0 deletions boards/renesas/rsk_rx130/rsk_rx130.dts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
aliases {
led0 = &led1;
led1 = &led3;
watchdog0 = &iwdt;
};
};

Expand All @@ -58,6 +59,10 @@
status = "okay";
};

&iwdtlsclk {
status = "okay";
};

&cmt {
clock-frequency = <4000000>;
status = "okay";
Expand Down Expand Up @@ -88,3 +93,9 @@
ssl-assert = <0>;
status = "okay";
};

&iwdt {
window-start = <0x3000>;
window-end = <0x0300>;
status = "okay";
};
1 change: 1 addition & 0 deletions boards/renesas/rsk_rx130/rsk_rx130_512kb.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ supported:
- serial
- timer
- spi
- watchdog
ram: 48
flash: 512
1 change: 1 addition & 0 deletions drivers/watchdog/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ zephyr_syscall_header(${ZEPHYR_BASE}/include/zephyr/drivers/watchdog.h)
zephyr_library()

zephyr_library_sources_ifdef(CONFIG_IWDG_STM32 wdt_iwdg_stm32.c)
zephyr_library_sources_ifdef(CONFIG_IWDT_RENESAS_RX wdt_iwdt_renesas_rx.c)
zephyr_library_sources_ifdef(CONFIG_WWDG_STM32 wdt_wwdg_stm32.c)

zephyr_library_sources_ifdef(CONFIG_FWDGT_GD32 wdt_fwdgt_gd32.c)
Expand Down
2 changes: 2 additions & 0 deletions drivers/watchdog/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ source "drivers/watchdog/Kconfig.rts5912"

source "drivers/watchdog/Kconfig.renesas_ra"

source "drivers/watchdog/Kconfig.renesas_rx"

source "drivers/watchdog/Kconfig.wch"

source "drivers/watchdog/Kconfig.nxp_ewm"
Expand Down
104 changes: 104 additions & 0 deletions drivers/watchdog/Kconfig.renesas_rx
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# Renesas RX Independent Watchdog (IWDT) configuration

# Copyright (c) 2025 Renesas Electronics Corporation
# SPDX-License-Identifier: Apache-2.0

config IWDT_RENESAS_RX
bool "Renesas RX Series Independent Watchdog Driver"
default y
depends on DT_HAS_RENESAS_RX_IWDT_ENABLED
select HAS_WDT_DISABLE_AT_BOOT
select USE_RX_RDP_IWDT
help
Enable Renesas RX series watchdog driver.

if IWDT_RENESAS_RX

config IWDT_RX_NMI
bool "Non-maskable interrupt for IWDT"
default y
help
Enable NMI for IWDT.

choice
prompt "IWDT Start Mode"
default IWDT_RENESAS_RX_IWDT
help
Select the IWDT start mode.
- IWDT_RENESAS_RX_AUTO_START_MODE: Counting automatically starts after a reset
(auto-start mode), controlled by option function select register 0 (OFS0).
- IWDT_RENESAS_RX_IWDT: Counting is started by refreshing the counter.
(controlled by the IWDT registers)

config IWDT_RENESAS_RX_AUTO_START_MODE
bool "Start IWDT automatically on reset"

config IWDT_RENESAS_RX_IWDT
bool "IWDT Start Mode Select"
select USE_RX_RDP_IWDT

endchoice

if IWDT_RENESAS_RX_AUTO_START_MODE

config IWDT_RENESAS_RX_IWDTSTRT
int "IWDT OFS0 Start Mode Select"
default 0
help
0: IWDT is automatically activated in auto-start mode after a reset
1: IWDT is halted after a reset

config IWDT_RENESAS_RX_OFS0_IWDTTOPS
int "IWDT Timeout Period Select"
default 3
help
0: 128 cycles (007Fh)
1: 512 cycles (01FFh)
2: 1024 cycles (03FFh)
3: 2048 cycles (07FFh)

config IWDT_RENESAS_RX_OFS0_IWDTCKS
int "IWDT Clock Divide Ratio Select"
default 15
help
0: No division
2: Divide-by-16
3: Divide-by-32
4: Divide-by-64
15: Divide-by-128
5: Divide-by-256

config IWDT_RENESAS_RX_OFS0_IWDTRPSS
int "IWDT Window Start Position Select"
default 3
help
0: 25%
1: 50%
2: 75%
3: 100% (window start position is not specified.)

config IWDT_RENESAS_RX_OFS0_IWDTRPES
int "IWDT Window End Position Select"
default 3
help
0: 75%
1: 50%
2: 25%
3: 0% (window end position is not specified.)

config IWDT_RENESAS_RX_OFS0_IWDTRSTIRQS
int "IWDT Reset Interrupt Request Select"
default 0
help
0: Non-maskable interrupt request output is enabled.
1: Reset output is enabled.

config IWDT_RENESAS_RX_OFS0_IWDTSLCSTP
int "IWDT Sleep Mode Count Stop Control"
default 0
help
0: Count stop is disabled.
1: Count is stopped at a transition to sleep mode, software standby mode, or deep sleep mode.

endif # IWDT_RENESAS_RX_AUTO_START_MODE
endif # IWDT_RENESAS_RX
Loading
Loading