Skip to content

Commit c09edc1

Browse files
lozyn888cfriedt
authored andcommitted
drivers: watchdog: Shift watchdog to pdl
Shift ifx_cat1 watchdog driver to using pdl instead of hal calls Signed-off-by: Yurii Lozynskyi <[email protected]>
1 parent 1f3fb17 commit c09edc1

File tree

3 files changed

+261
-10
lines changed

3 files changed

+261
-10
lines changed

boards/infineon/cy8cproto_062_4343w/cy8cproto_062_4343w.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,5 @@ supported:
2626
- uart
2727
- dma
2828
- timer
29+
- watchdog
2930
vendor: infineon

boards/infineon/cyw920829m2evk_02/cyw920829m2evk_02.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,5 @@ supported:
2424
- rtc
2525
- dma
2626
- pwm
27-
27+
- watchdog
2828
vendor: infineon

drivers/watchdog/wdt_ifx_cat1.c

Lines changed: 259 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77

88
#define DT_DRV_COMPAT infineon_cat1_watchdog
99

10-
#include "cyhal_wdt.h"
10+
#include "cy_wdt.h"
11+
#include "cy_sysclk.h"
1112

1213
#include <zephyr/devicetree.h>
1314
#include <zephyr/drivers/watchdog.h>
@@ -17,16 +18,211 @@ LOG_MODULE_REGISTER(wdt_infineon_cat1, CONFIG_WDT_LOG_LEVEL);
1718

1819
#define IFX_CAT1_WDT_IS_IRQ_EN DT_NODE_HAS_PROP(DT_DRV_INST(0), interrupts)
1920

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+
20187
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;
22192
#ifdef IFX_CAT1_WDT_IS_IRQ_EN
23193
wdt_callback_t callback;
24194
#endif /* IFX_CAT1_WDT_IS_IRQ_EN */
25195
uint32_t timeout;
26196
bool timeout_installed;
27197
};
28198

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+
}
30226

31227
#ifdef IFX_CAT1_WDT_IS_IRQ_EN
32228
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)
42238

43239
static int ifx_cat1_wdt_setup(const struct device *dev, uint8_t options)
44240
{
45-
cy_rslt_t result;
46241
struct ifx_cat1_wdt_data *dev_data = dev->data;
47242

48243
/* 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()) {
52294
return -ENOMSG;
53295
}
54296

@@ -71,7 +313,11 @@ static int ifx_cat1_wdt_disable(const struct device *dev)
71313
irq_disable(DT_INST_IRQN(0));
72314
#endif /* IFX_CAT1_WDT_IS_IRQ_EN */
73315

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;
75321

76322
return 0;
77323
}
@@ -116,7 +362,11 @@ static int ifx_cat1_wdt_feed(const struct device *dev, int channel_id)
116362
return -EINVAL;
117363
}
118364

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();
120370

121371
return 0;
122372
}

0 commit comments

Comments
 (0)