11/*
2- * Copyright 2023 Cypress Semiconductor Corporation (an Infineon company) or
3- * an affiliate of Cypress Semiconductor Corporation
2+ * Copyright (c) 2025 Infineon Technologies AG,
3+ * or an affiliate of Infineon Technologies AG.
44 *
55 * SPDX-License-Identifier: Apache-2.0
66 */
77
8+ /* Watchdog timer driver for the Infineon MCU family. */
9+
810#define DT_DRV_COMPAT infineon_cat1_watchdog
911
1012#include "cy_wdt.h"
@@ -19,13 +21,9 @@ LOG_MODULE_REGISTER(wdt_infineon_cat1, CONFIG_WDT_LOG_LEVEL);
1921#define IFX_CAT1_WDT_IS_IRQ_EN DT_NODE_HAS_PROP(DT_DRV_INST(0), interrupts)
2022
2123typedef struct {
22- /* Minimum period in milliseconds that can be represented with this
23- * many ignored bits
24- */
24+ /* Minimum period in milliseconds that can be represented with this many ignored bits */
2525 uint32_t min_period_ms ;
26- /* Timeout threshold in milliseconds from which to round up to
27- * the minimum period
28- */
26+ /* Timeout threshold in milliseconds from which to round up to the minimum period */
2927 uint32_t round_threshold_ms ;
3028} wdt_ignore_bits_data_t ;
3129
@@ -39,9 +37,11 @@ typedef struct {
3937
4038#if defined(SRSS_NUM_WDT_A_BITS )
4139#define IFX_WDT_MATCH_BITS (SRSS_NUM_WDT_A_BITS)
42- #elif defined(COMPONENT_CAT1A )
40+ #elif defined(COMPONENT_CAT1A ) || defined( COMPONENT_CAT1C )
4341#if defined(CY_IP_MXS40SRSS ) && (CY_IP_MXS40SRSS_VERSION < 2 )
4442#define IFX_WDT_MATCH_BITS (16)
43+ #else
44+ #define IFX_WDT_MATCH_BITS (32)
4545#endif
4646#elif defined(COMPONENT_CAT1B )
4747#define IFX_WDT_MATCH_BITS (16)
@@ -55,26 +55,30 @@ typedef struct {
5555 * Max WDT Reset Period = 3 * (2^IFX_WDT_MATCH_BITS) * CLK_DURATION
5656 */
5757#if defined(CY_IP_MXS40SRSS )
58+ #if (CY_IP_MXS40SRSS_VERSION >= 2 )
59+ #define IFX_WDT_MAX_TIMEOUT_MS 131073812
60+ #else
5861/* ILO, PILO, BAK all run at 32768 Hz - Period is ~0.030518 ms */
5962#define IFX_WDT_MAX_TIMEOUT_MS 6000
6063#define IFX_WDT_MAX_IGNORE_BITS 12
6164/* ILO Frequency = 32768 Hz, ILO Period = 1 / 32768 Hz = .030518 ms */
6265static const wdt_ignore_bits_data_t ifx_wdt_ignore_data [] = {
63- {4000 , 3001 }, /* 0 bit(s): min period: 4000ms, max period: 6000ms, round up from 3001+ms */
64- {2000 , 1501 }, /* 1 bit(s): min period: 2000ms, max period: 3000ms, round up from 1501+ms */
65- {1000 , 751 }, /* 2 bit(s): min period: 1000ms, max period: 1500ms, round up from 751+ms */
66- {500 , 376 }, /* 3 bit(s): min period: 500ms, max period: 750ms, round up from 376+ms */
67- {250 , 188 }, /* 4 bit(s): min period: 250ms, max period: 375ms, round up from 188+ms */
68- {125 , 94 }, /* 5 bit(s): min period: 125ms, max period: 187ms, round up from 94+ms */
69- {63 , 47 }, /* 6 bit(s): min period: 63ms, max period: 93ms, round up from 47+ms */
70- {32 , 24 }, /* 7 bit(s): min period: 32ms, max period: 46ms, round up from 24+ms */
71- {16 , 12 }, /* 8 bit(s): min period: 16ms, max period: 23ms, round up from 12+ms */
72- {8 , 6 }, /* 9 bit(s): min period: 8ms, max period: 11ms, round up from 6+ms */
66+ {4000 , 3001 }, /* 0 bit(s): min period: 4000ms, max period: 6000ms, round up from 3001+ms */
67+ {2000 , 1501 }, /* 1 bit(s): min period: 2000ms, max period: 3000ms, round up from 1501+ms */
68+ {1000 , 751 }, /* 2 bit(s): min period: 1000ms, max period: 1500ms, round up from 751+ms */
69+ {500 , 376 }, /* 3 bit(s): min period: 500ms, max period: 750ms, round up from 376+ms */
70+ {250 , 188 }, /* 4 bit(s): min period: 250ms, max period: 375ms, round up from 188+ms */
71+ {125 , 94 }, /* 5 bit(s): min period: 125ms, max period: 187ms, round up from 94+ms */
72+ {63 , 47 }, /* 6 bit(s): min period: 63ms, max period: 93ms, round up from 47+ms */
73+ {32 , 24 }, /* 7 bit(s): min period: 32ms, max period: 46ms, round up from 24+ms */
74+ {16 , 12 }, /* 8 bit(s): min period: 16ms, max period: 23ms, round up from 12+ms */
75+ {8 , 6 }, /* 9 bit(s): min period: 8ms, max period: 11ms, round up from 6+ms */
7376 {4 , 3 }, /* 10 bit(s): min period: 4ms, max period: 5ms, round up from 3+ms */
7477 {2 , 2 }, /* 11 bit(s): min period: 2ms, max period: 2ms, round up from 2+ms */
7578 {1 , 1 }, /* 12 bit(s): min period: 1ms, max period: 1ms, round up from 1+ms */
7679};
77- #elif defined(CY_IP_MXS40SSRSS ) && (IFX_WDT_MATCH_BITS == 22 )
80+ #endif
81+ #elif (defined(CY_IP_MXS40SSRSS ) || defined(CY_IP_MXS22SRSS )) && (IFX_WDT_MATCH_BITS == 22 )
7882/* ILO Frequency = 32768 Hz, ILO Period = 1 / 32768 Hz = .030518 ms */
7983#define IFX_WDT_MAX_TIMEOUT_MS 384000
8084#define IFX_WDT_MAX_IGNORE_BITS (IFX_WDT_MATCH_BITS - 4)
@@ -83,21 +87,21 @@ static const wdt_ignore_bits_data_t ifx_wdt_ignore_data[] = {
8387 {256000 , 192001 },
8488 /* 1 bit(s): min period: 128000ms, max period: 192000ms, round up from 96001+ms */
8589 {128000 , 96001 },
86- /* 2 bit(s): min period: 64000ms, max period: 96000ms, round up from 48001+ms */
90+ /* 2 bit(s): min period: 64000ms, max period: 96000ms, round up from 48001+ms */
8791 {64000 , 48001 },
88- /* 3 bit(s): min period: 32000ms, max period: 48000ms, round up from 24001+ms */
92+ /* 3 bit(s): min period: 32000ms, max period: 48000ms, round up from 24001+ms */
8993 {32000 , 24001 },
90- /* 4 bit(s): min period: 16000ms, max period: 24000ms, round up from 12001+ms */
94+ /* 4 bit(s): min period: 16000ms, max period: 24000ms, round up from 12001+ms */
9195 {16000 , 12001 },
92- /* 5 bit(s): min period:8000ms, max period: 12000ms, round up from 6001+ms */
96+ /* 5 bit(s): min period: 8000ms, max period: 12000ms, round up from 6001+ms */
9397 {8000 , 6001 },
94- /* 6 bit(s): min period:4000ms, max period:6000ms, round up from 3001+ms */
98+ /* 6 bit(s): min period: 4000ms, max period: 6000ms, round up from 3001+ms */
9599 {4000 , 3001 },
96- /* 7 bit(s): min period:2000ms, max period:3000ms, round up from 1501+ms */
100+ /* 7 bit(s): min period: 2000ms, max period: 3000ms, round up from 1501+ms */
97101 {2000 , 1501 },
98- /* 8 bit(s): min period:1000ms, max period:1500ms, round up from 751+ms */
102+ /* 8 bit(s): min period: 1000ms, max period: 1500ms, round up from 751+ms */
99103 {1000 , 751 },
100- /* 9 bit(s): min period: 500ms, max period: 750ms, round up from 376+ms */
104+ /* 9 bit(s): min period: 500ms, max period: 750ms, round up from 376+ms */
101105 {500 , 376 },
102106 /* 10 bit(s): min period: 250ms, max period: 375ms, round up from 188+ms */
103107 {250 , 188 },
@@ -182,6 +186,8 @@ static const wdt_ignore_bits_data_t ifx_wdt_ignore_data[] = {
182186 /* 28 bit(s): min period: 1ms, max period: 1ms, round up from 1+ms */
183187 {1 , 1 },
184188};
189+ #else
190+ #error "Device not supported"
185191#endif
186192
187193struct ifx_cat1_wdt_data {
@@ -191,7 +197,7 @@ struct ifx_cat1_wdt_data {
191197 uint32_t wdt_ignore_bits ;
192198#ifdef IFX_CAT1_WDT_IS_IRQ_EN
193199 wdt_callback_t callback ;
194- #endif /* IFX_CAT1_WDT_IS_IRQ_EN */
200+ #endif
195201 uint32_t timeout ;
196202 bool timeout_installed ;
197203};
@@ -234,18 +240,20 @@ static void ifx_cat1_wdt_isr_handler(const struct device *dev)
234240 }
235241 Cy_WDT_MaskInterrupt ();
236242}
237- #endif /* IFX_CAT1_WDT_IS_IRQ_EN */
243+ #endif
238244
239245static int ifx_cat1_wdt_setup (const struct device * dev , uint8_t options )
240246{
241247 struct ifx_cat1_wdt_data * dev_data = dev -> data ;
242248
243249 /* Initialize the WDT */
244250 if ((dev_data -> timeout == 0 ) || (dev_data -> timeout > IFX_WDT_MAX_TIMEOUT_MS )) {
251+ LOG_ERR ("Invalid timeout" );
245252 return - ENOTSUP ;
246253 }
247254
248255 if (dev_data -> wdt_initialized ) {
256+ LOG_ERR ("Already initialized" );
249257 return - EBUSY ;
250258 }
251259
@@ -274,7 +282,8 @@ static int ifx_cat1_wdt_setup(const struct device *dev, uint8_t options)
274282#endif
275283
276284#if defined(COMPONENT_CAT1 ) && (CY_WDT_DRV_VERSION_MAJOR > 1 ) && (CY_WDT_DRV_VERSION_MINOR > 6 )
277- /* Reset counter every time - large current counts in WDT can cause problems on some boards
285+ /* Reset counter every time
286+ * Large current counts in WDT can cause problems on some boards
278287 */
279288 Cy_WDT_ResetCounter ();
280289 /* Twice, as reading back after 1 reset gives same value as before single reset */
@@ -285,6 +294,7 @@ static int ifx_cat1_wdt_setup(const struct device *dev, uint8_t options)
285294 dev_data -> wdt_ignore_bits ));
286295#endif
287296
297+ ifx_wdt_unlock ();
288298 Cy_WDT_Enable ();
289299 ifx_wdt_lock ();
290300
@@ -299,7 +309,7 @@ static int ifx_cat1_wdt_setup(const struct device *dev, uint8_t options)
299309 Cy_WDT_UnmaskInterrupt ();
300310 irq_enable (DT_INST_IRQN (0 ));
301311 }
302- #endif /* IFX_CAT1_WDT_IS_IRQ_EN */
312+ #endif
303313
304314 return 0 ;
305315}
@@ -311,7 +321,7 @@ static int ifx_cat1_wdt_disable(const struct device *dev)
311321#ifdef IFX_CAT1_WDT_IS_IRQ_EN
312322 Cy_WDT_MaskInterrupt ();
313323 irq_disable (DT_INST_IRQN (0 ));
314- #endif /* IFX_CAT1_WDT_IS_IRQ_EN */
324+ #endif
315325
316326 ifx_wdt_unlock ();
317327 Cy_WDT_Disable ();
@@ -331,19 +341,19 @@ static int ifx_cat1_wdt_install_timeout(const struct device *dev, const struct w
331341 return - ENOMEM ;
332342 }
333343
334- if (cfg -> flags ) {
335- LOG_WRN ("Watchdog behavior is not configurable. " );
344+ if (cfg -> flags && cfg -> flags != WDT_FLAG_RESET_SOC ) {
345+ LOG_WRN ("Watchdog config flags not supported " );
336346 }
337347
338348 if (cfg -> callback ) {
339349#ifndef IFX_CAT1_WDT_IS_IRQ_EN
340350 LOG_WRN ("Interrupt is not configured, can't set a callback." );
341351#else
342352 dev_data -> callback = cfg -> callback ;
343- #endif /* IFX_CAT1_WDT_IS_IRQ_EN */
353+ #endif
344354 }
345355
346- /* window watchdog not supported */
356+ /* Window watchdog not supported */
347357 if (cfg -> window .min != 0U || cfg -> window .max == 0U ) {
348358 return - EINVAL ;
349359 }
@@ -364,20 +374,25 @@ static int ifx_cat1_wdt_feed(const struct device *dev, int channel_id)
364374
365375 ifx_wdt_unlock ();
366376 Cy_WDT_ClearWatchdog (); /* Clear to prevent reset from WDT */
367- Cy_WDT_SetMatch (
368- ifx_wdt_timeout_to_match ( data -> wdt_rounded_timeout_ms , data -> wdt_ignore_bits ));
377+ Cy_WDT_SetMatch (ifx_wdt_timeout_to_match ( data -> wdt_rounded_timeout_ms ,
378+ data -> wdt_ignore_bits ));
369379 ifx_wdt_lock ();
370380
371381 return 0 ;
372382}
373383
374384static int ifx_cat1_wdt_init (const struct device * dev )
375385{
386+ struct ifx_cat1_wdt_data * data = dev -> data ;
376387#ifdef IFX_CAT1_WDT_IS_IRQ_EN
377388 /* Connect WDT interrupt to ISR */
378389 IRQ_CONNECT (DT_INST_IRQN (0 ), DT_INST_IRQ (0 , priority ), ifx_cat1_wdt_isr_handler ,
379390 DEVICE_DT_INST_GET (0 ), 0 );
380- #endif /* IFX_CAT1_WDT_IS_IRQ_EN */
391+ #endif
392+
393+ data -> wdt_initialized = false;
394+ data -> wdt_initial_timeout_ms = 0 ;
395+ data -> wdt_rounded_timeout_ms = 0 ;
381396
382397 return 0 ;
383398}
0 commit comments