7
7
8
8
#define DT_DRV_COMPAT infineon_cat1_watchdog
9
9
10
- #include "cyhal_wdt.h"
10
+ #include "cy_wdt.h"
11
+ #include "cy_sysclk.h"
11
12
12
13
#include <zephyr/devicetree.h>
13
14
#include <zephyr/drivers/watchdog.h>
@@ -17,16 +18,211 @@ LOG_MODULE_REGISTER(wdt_infineon_cat1, CONFIG_WDT_LOG_LEVEL);
17
18
18
19
#define IFX_CAT1_WDT_IS_IRQ_EN DT_NODE_HAS_PROP(DT_DRV_INST(0), interrupts)
19
20
21
+ typedef struct {
22
+ /* Minimum period in milliseconds that can be represented with this
23
+ * many ignored bits
24
+ */
25
+ uint32_t min_period_ms ;
26
+ /* Timeout threshold in milliseconds from which to round up to
27
+ * the minimum period
28
+ */
29
+ uint32_t round_threshold_ms ;
30
+ } wdt_ignore_bits_data_t ;
31
+
32
+ #if defined(CY_IP_MXS40SRSS ) || defined(CY_IP_MXS40SSRSS )
33
+ #define ifx_wdt_lock () Cy_WDT_Lock()
34
+ #define ifx_wdt_unlock () Cy_WDT_Unlock()
35
+ #else
36
+ #define ifx_wdt_lock ()
37
+ #define ifx_wdt_unlock ()
38
+ #endif
39
+
40
+ #if defined(SRSS_NUM_WDT_A_BITS )
41
+ #define IFX_WDT_MATCH_BITS (SRSS_NUM_WDT_A_BITS)
42
+ #elif defined(COMPONENT_CAT1A )
43
+ #if defined(CY_IP_MXS40SRSS ) && (CY_IP_MXS40SRSS_VERSION < 2 )
44
+ #define IFX_WDT_MATCH_BITS (16)
45
+ #endif
46
+ #elif defined(COMPONENT_CAT1B )
47
+ #define IFX_WDT_MATCH_BITS (16)
48
+ #else
49
+ #error Unhandled device type
50
+ #endif
51
+
52
+ /* match range: 0 -> 2^(IFX_WDT_MATCH_BITS - ignore_bits)
53
+ * ignore_bits range: 0 -> (IFX_WDT_MATCH_BITS - 4) (Bottom four bits cannot be ignored)
54
+ * WDT Reset Period (timeout_ms) = CLK_DURATION * (2 * 2^(IFX_WDT_MATCH_BITS - ignore_bits) + match)
55
+ * Max WDT Reset Period = 3 * (2^IFX_WDT_MATCH_BITS) * CLK_DURATION
56
+ */
57
+ #if defined(CY_IP_MXS40SRSS )
58
+ /* ILO, PILO, BAK all run at 32768 Hz - Period is ~0.030518 ms */
59
+ #define IFX_WDT_MAX_TIMEOUT_MS 6000
60
+ #define IFX_WDT_MAX_IGNORE_BITS 12
61
+ /* ILO Frequency = 32768 Hz, ILO Period = 1 / 32768 Hz = .030518 ms */
62
+ static 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 */
73
+ {4 , 3 }, /* 10 bit(s): min period: 4ms, max period: 5ms, round up from 3+ms */
74
+ {2 , 2 }, /* 11 bit(s): min period: 2ms, max period: 2ms, round up from 2+ms */
75
+ {1 , 1 }, /* 12 bit(s): min period: 1ms, max period: 1ms, round up from 1+ms */
76
+ };
77
+ #elif defined(CY_IP_MXS40SSRSS ) && (IFX_WDT_MATCH_BITS == 22 )
78
+ /* ILO Frequency = 32768 Hz, ILO Period = 1 / 32768 Hz = .030518 ms */
79
+ #define IFX_WDT_MAX_TIMEOUT_MS 384000
80
+ #define IFX_WDT_MAX_IGNORE_BITS (IFX_WDT_MATCH_BITS - 4)
81
+ static const wdt_ignore_bits_data_t ifx_wdt_ignore_data [] = {
82
+ /* 0 bit(s): min period: 256000ms, max period: 384000ms, round up from 192001+ms */
83
+ {256000 , 192001 },
84
+ /* 1 bit(s): min period: 128000ms, max period: 192000ms, round up from 96001+ms */
85
+ {128000 , 96001 },
86
+ /* 2 bit(s): min period: 64000ms, max period: 96000ms, round up from 48001+ms */
87
+ {64000 , 48001 },
88
+ /* 3 bit(s): min period: 32000ms, max period: 48000ms, round up from 24001+ms */
89
+ {32000 , 24001 },
90
+ /* 4 bit(s): min period: 16000ms, max period: 24000ms, round up from 12001+ms */
91
+ {16000 , 12001 },
92
+ /* 5 bit(s): min period:8000ms, max period: 12000ms, round up from 6001+ms */
93
+ {8000 , 6001 },
94
+ /* 6 bit(s): min period:4000ms, max period:6000ms, round up from 3001+ms */
95
+ {4000 , 3001 },
96
+ /* 7 bit(s): min period:2000ms, max period:3000ms, round up from 1501+ms */
97
+ {2000 , 1501 },
98
+ /* 8 bit(s): min period:1000ms, max period:1500ms, round up from 751+ms */
99
+ {1000 , 751 },
100
+ /* 9 bit(s): min period: 500ms, max period: 750ms, round up from 376+ms */
101
+ {500 , 376 },
102
+ /* 10 bit(s): min period: 250ms, max period: 375ms, round up from 188+ms */
103
+ {250 , 188 },
104
+ /* 11 bit(s): min period: 125ms, max period: 187ms, round up from 94+ms */
105
+ {125 , 94 },
106
+ /* 12 bit(s): min period: 63ms, max period: 93ms, round up from 47+ms */
107
+ {63 , 47 },
108
+ /* 13 bit(s): min period: 32ms, max period: 46ms, round up from 24+ms */
109
+ {32 , 24 },
110
+ /* 14 bit(s): min period: 16ms, max period: 23ms, round up from 12+ms */
111
+ {16 , 12 },
112
+ /* 15 bit(s): min period: 8ms, max period: 11ms, round up from 6+ms */
113
+ {8 , 6 },
114
+ /* 16 bit(s): min period: 4ms, max period: 5ms, round up from 3+ms */
115
+ {4 , 3 },
116
+ /* 17 bit(s): min period: 2ms, max period: 2ms, round up from 2+ms */
117
+ {2 , 2 },
118
+ /* 18 bit(s): min period: 1ms, max period: 1ms, round up from 1+ms */
119
+ {1 , 1 },
120
+ };
121
+ #elif defined(CY_IP_MXS40SSRSS ) && (IFX_WDT_MATCH_BITS == 32 )
122
+ /* ILO Frequency = 32768 Hz, ILO Period = 1 / 32768 Hz = .030518 ms */
123
+ #define IFX_WDT_MAX_TIMEOUT_MS 393211435
124
+ #define IFX_WDT_MAX_IGNORE_BITS (IFX_WDT_MATCH_BITS - 4)
125
+ static const wdt_ignore_bits_data_t ifx_wdt_ignore_data [] = {
126
+ /* 0 bit(s): min period: 262147000ms, max period: 393221000ms, round up from 196610001+ms */
127
+ {262147000 , 196610001 },
128
+ /* 1 bit(s): min period: 131073000ms, max period: 196610000ms, round up from 98305001+ms */
129
+ {131073000 , 98305001 },
130
+ /* 2 bit(s): min period: 65537000ms, max period: 98305000ms, round up from 49152001+ms */
131
+ {65537000 , 49152001 },
132
+ /* 3 bit(s): min period: 32768000ms, max period: 49152000ms, round up from 24576001+ms */
133
+ {32768000 , 24576001 },
134
+ /* 4 bit(s): min period: 16384000ms, max period: 24576000ms, round up from 12288001+ms */
135
+ {16384000 , 12288001 },
136
+ /* 5 bit(s): min period: 8192000ms, max period: 12288000ms, round up from 6144001+ms */
137
+ {8192000 , 6144001 },
138
+ /* 6 bit(s): min period: 4096000ms, max period: 6144000ms, round up from 3072001+ms */
139
+ {4096000 , 3072001 },
140
+ /* 7 bit(s): min period: 2048000ms, max period: 3072000ms, round up from 1536001+ms */
141
+ {2048000 , 1536001 },
142
+ /* 8 bit(s): min period: 1024000ms, max period: 1536000ms, round up from 768001+ms */
143
+ {1024000 , 768001 },
144
+ /* 9 bit(s): min period: 512000ms, max period: 768000ms, round up from 384001+ms */
145
+ {512000 , 384001 },
146
+ /* 10 bit(s): min period: 256000ms, max period: 384000ms, round up from 192001+ms */
147
+ {256000 , 192001 },
148
+ /* 11 bit(s): min period: 128000ms, max period: 192000ms, round up from 96001+ms */
149
+ {128000 , 96001 },
150
+ /* 12 bit(s): min period: 64000ms, max period: 96000ms, round up from 48001+ms */
151
+ {64000 , 48001 },
152
+ /* 13 bit(s): min period: 32000ms, max period: 48000ms, round up from 24001+ms */
153
+ {32000 , 24001 },
154
+ /* 14 bit(s): min period: 16000ms, max period: 24000ms, round up from 12001+ms */
155
+ {16000 , 12001 },
156
+ /* 15 bit(s): min period: 8000ms, max period: 12000ms, round up from 6001+ms */
157
+ {8000 , 6001 },
158
+ /* 16 bit(s): min period: 4000ms, max period: 6000ms, round up from 3001+ms */
159
+ {4000 , 3001 },
160
+ /* 17 bit(s): min period: 2000ms, max period: 3000ms, round up from 1501+ms */
161
+ {2000 , 1501 },
162
+ /* 18 bit(s): min period: 1000ms, max period: 1500ms, round up from 751+ms */
163
+ {1000 , 751 },
164
+ /* 19 bit(s): min period: 500ms, max period: 750ms, round up from 376+ms */
165
+ {500 , 376 },
166
+ /* 20 bit(s): min period: 250ms, max period: 375ms, round up from 188+ms */
167
+ {250 , 188 },
168
+ /* 21 bit(s): min period: 125ms, max period: 187ms, round up from 94+ms */
169
+ {125 , 94 },
170
+ /* 22 bit(s): min period: 63ms, max period: 93ms, round up from 47+ms */
171
+ {63 , 47 },
172
+ /* 23 bit(s): min period: 32ms, max period: 46ms, round up from 24+ms */
173
+ {32 , 24 },
174
+ /* 24 bit(s): min period: 16ms, max period: 23ms, round up from 12+ms */
175
+ {16 , 12 },
176
+ /* 25 bit(s): min period: 8ms, max period: 11ms, round up from 6+ms */
177
+ {8 , 6 },
178
+ /* 26 bit(s): min period: 4ms, max period: 5ms, round up from 3+ms */
179
+ {4 , 3 },
180
+ /* 27 bit(s): min period: 2ms, max period: 2ms, round up from 2+ms */
181
+ {2 , 2 },
182
+ /* 28 bit(s): min period: 1ms, max period: 1ms, round up from 1+ms */
183
+ {1 , 1 },
184
+ };
185
+ #endif
186
+
20
187
struct ifx_cat1_wdt_data {
21
- cyhal_wdt_t obj ;
188
+ bool wdt_initialized ;
189
+ uint32_t wdt_initial_timeout_ms ;
190
+ uint32_t wdt_rounded_timeout_ms ;
191
+ uint32_t wdt_ignore_bits ;
22
192
#ifdef IFX_CAT1_WDT_IS_IRQ_EN
23
193
wdt_callback_t callback ;
24
194
#endif /* IFX_CAT1_WDT_IS_IRQ_EN */
25
195
uint32_t timeout ;
26
196
bool timeout_installed ;
27
197
};
28
198
29
- struct ifx_cat1_wdt_data wdt_data ;
199
+ static struct ifx_cat1_wdt_data wdt_data ;
200
+
201
+ #define IFX_DETERMINE_MATCH_BITS (bits ) ((IFX_WDT_MAX_IGNORE_BITS) - (bits))
202
+ #define IFX_GET_COUNT_FROM_MATCH_BITS (bits ) (2UL << IFX_DETERMINE_MATCH_BITS(bits))
203
+
204
+ __STATIC_INLINE uint32_t ifx_wdt_timeout_to_match (uint32_t timeout_ms , uint32_t ignore_bits )
205
+ {
206
+ uint32_t wrap_count_for_ignore_bits = (IFX_GET_COUNT_FROM_MATCH_BITS (ignore_bits ));
207
+ uint32_t timeout_count = ((timeout_ms * CY_SYSCLK_ILO_FREQ ) / 1000UL );
208
+ /* handle multiple possible wraps of WDT counter */
209
+ timeout_count = ((timeout_count + Cy_WDT_GetCount ()) % wrap_count_for_ignore_bits );
210
+ return timeout_count ;
211
+ }
212
+
213
+ /* Rounds up *timeout_ms if it's outside of the valid timeout range (ifx_wdt_ignore_data) */
214
+ __STATIC_INLINE uint32_t ifx_wdt_timeout_to_ignore_bits (uint32_t * timeout_ms )
215
+ {
216
+ for (uint32_t i = 0 ; i <= IFX_WDT_MAX_IGNORE_BITS ; i ++ ) {
217
+ if (* timeout_ms >= ifx_wdt_ignore_data [i ].round_threshold_ms ) {
218
+ if (* timeout_ms < ifx_wdt_ignore_data [i ].min_period_ms ) {
219
+ * timeout_ms = ifx_wdt_ignore_data [i ].min_period_ms ;
220
+ }
221
+ return i ;
222
+ }
223
+ }
224
+ return IFX_WDT_MAX_IGNORE_BITS ; /* Ideally should never reach this */
225
+ }
30
226
31
227
#ifdef IFX_CAT1_WDT_IS_IRQ_EN
32
228
static void ifx_cat1_wdt_isr_handler (const struct device * dev )
@@ -42,13 +238,59 @@ static void ifx_cat1_wdt_isr_handler(const struct device *dev)
42
238
43
239
static int ifx_cat1_wdt_setup (const struct device * dev , uint8_t options )
44
240
{
45
- cy_rslt_t result ;
46
241
struct ifx_cat1_wdt_data * dev_data = dev -> data ;
47
242
48
243
/* Initialize the WDT */
49
- result = cyhal_wdt_init (& dev_data -> obj , dev_data -> timeout );
50
- if (result != CY_RSLT_SUCCESS ) {
51
- LOG_ERR ("Initialization failure : 0x%x" , result );
244
+ if ((dev_data -> timeout == 0 ) || (dev_data -> timeout > IFX_WDT_MAX_TIMEOUT_MS )) {
245
+ return - ENOTSUP ;
246
+ }
247
+
248
+ if (dev_data -> wdt_initialized ) {
249
+ return - EBUSY ;
250
+ }
251
+
252
+ /* Unlock and disable before doing other work */
253
+ ifx_wdt_unlock ();
254
+ Cy_WDT_Disable ();
255
+
256
+ Cy_WDT_ClearInterrupt ();
257
+ Cy_WDT_MaskInterrupt ();
258
+
259
+ dev_data -> wdt_initial_timeout_ms = dev_data -> timeout ;
260
+ #if defined(CY_IP_MXS40SRSS ) && (CY_IP_MXS40SRSS_VERSION >= 2 )
261
+ Cy_WDT_SetUpperLimit (ifx_wdt_timeout_to_match (dev_data -> wdt_initial_timeout_ms ));
262
+ Cy_WDT_SetUpperAction (CY_WDT_LOW_UPPER_LIMIT_ACTION_RESET );
263
+ #else
264
+ dev_data -> wdt_ignore_bits = ifx_wdt_timeout_to_ignore_bits (& dev_data -> timeout );
265
+ dev_data -> wdt_rounded_timeout_ms = dev_data -> timeout ;
266
+ #if defined(SRSS_NUM_WDT_A_BITS ) && (SRSS_NUM_WDT_A_BITS == 22 )
267
+ /* Cy_WDT_SetMatchBits configures the bit position above which the bits will be ignored for
268
+ * match, while ifx_wdt_timeout_to_ignore_bits returns number of timer MSB to ignore, so
269
+ * conversion is needed.
270
+ */
271
+ Cy_WDT_SetMatchBits (IFX_DETERMINE_MATCH_BITS (dev_data -> wdt_ignore_bits ));
272
+ #else
273
+ Cy_WDT_SetIgnoreBits (dev_data -> wdt_ignore_bits );
274
+ #endif
275
+
276
+ #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
278
+ */
279
+ Cy_WDT_ResetCounter ();
280
+ /* Twice, as reading back after 1 reset gives same value as before single reset */
281
+ Cy_WDT_ResetCounter ();
282
+ #endif
283
+
284
+ Cy_WDT_SetMatch (ifx_wdt_timeout_to_match (dev_data -> wdt_rounded_timeout_ms ,
285
+ dev_data -> wdt_ignore_bits ));
286
+ #endif
287
+
288
+ Cy_WDT_Enable ();
289
+ ifx_wdt_lock ();
290
+
291
+ dev_data -> wdt_initialized = true;
292
+
293
+ if (!Cy_WDT_IsEnabled ()) {
52
294
return - ENOMSG ;
53
295
}
54
296
@@ -71,7 +313,11 @@ static int ifx_cat1_wdt_disable(const struct device *dev)
71
313
irq_disable (DT_INST_IRQN (0 ));
72
314
#endif /* IFX_CAT1_WDT_IS_IRQ_EN */
73
315
74
- cyhal_wdt_free (& dev_data -> obj );
316
+ ifx_wdt_unlock ();
317
+ Cy_WDT_Disable ();
318
+ ifx_wdt_lock ();
319
+
320
+ dev_data -> wdt_initialized = false;
75
321
76
322
return 0 ;
77
323
}
@@ -116,7 +362,11 @@ static int ifx_cat1_wdt_feed(const struct device *dev, int channel_id)
116
362
return - EINVAL ;
117
363
}
118
364
119
- cyhal_wdt_kick (& data -> obj );
365
+ ifx_wdt_unlock ();
366
+ 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 ));
369
+ ifx_wdt_lock ();
120
370
121
371
return 0 ;
122
372
}
0 commit comments