Skip to content

Commit 8a254a9

Browse files
authored
Merge pull request #12923 from OpenNuvoton/nuvoton_watchdog_lxt
Nuvoton: Refine more on watchdog HAL
2 parents 35c6747 + 9e9e2f1 commit 8a254a9

File tree

4 files changed

+153
-29
lines changed

4 files changed

+153
-29
lines changed

targets/TARGET_NUVOTON/TARGET_M451/watchdog_api.c

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,30 @@
2121

2222
#include "cmsis.h"
2323

24-
/* Micro seconds per second */
25-
#define NU_US_PER_SEC 1000000
24+
/* Define WDT clock source in target configuration option */
25+
#ifndef MBED_CONF_TARGET_WDT_CLKSRC_SEL
26+
#define MBED_CONF_TARGET_WDT_CLKSRC_SEL LXT
27+
#endif
28+
29+
/* WDT clock source definition */
30+
#define NU_INTERN_WDT_CLKSRC_LXT 1
31+
#define NU_INTERN_WDT_CLKSRC_LIRC 2
32+
33+
/* WDT clock source selection */
34+
#define NU_INTERN_WDT_CLKSRC_SEL__(SEL) NU_INTERN_WDT_CLKSRC_##SEL
35+
#define NU_INTERN_WDT_CLKSRC_SEL_(SEL) NU_INTERN_WDT_CLKSRC_SEL__(SEL)
36+
#define NU_INTERN_WDT_CLKSRC_SEL NU_INTERN_WDT_CLKSRC_SEL_(MBED_CONF_TARGET_WDT_CLKSRC_SEL)
2637

2738
/* Watchdog clock per second */
39+
#if NU_INTERN_WDT_CLKSRC_SEL == NU_INTERN_WDT_CLKSRC_LXT
40+
#define NU_WDTCLK_PER_SEC (__LXT)
41+
#define NU_WDTCLK_PER_SEC_MAX (__LXT)
42+
#define NU_WDTCLK_PER_SEC_MIN (__LXT)
43+
#elif NU_INTERN_WDT_CLKSRC_SEL == NU_INTERN_WDT_CLKSRC_LIRC
2844
#define NU_WDTCLK_PER_SEC (__LIRC)
45+
#define NU_WDTCLK_PER_SEC_MAX ((uint32_t) ((__LIRC) * 1.5f))
46+
#define NU_WDTCLK_PER_SEC_MIN ((uint32_t) ((__LIRC) * 0.5f))
47+
#endif
2948

3049
/* Convert watchdog clock to nearest ms */
3150
#define NU_WDTCLK2MS(WDTCLK) (((WDTCLK) * 1000 + ((NU_WDTCLK_PER_SEC) / 2)) / (NU_WDTCLK_PER_SEC))
@@ -43,8 +62,12 @@
4362
#define NU_WDT_65536CLK 65536
4463
#define NU_WDT_262144CLK 262144
4564

46-
/* Watchdog reset delay */
47-
#define NU_WDT_RESET_DELAY_RSTDSEL WDT_RESET_DELAY_3CLK
65+
/* Watchdog reset delay
66+
*
67+
* 1. Cannot be too small. This is to avoid premature WDT reset in pieces of timeout cascading.
68+
* 2. Cannot be too large. This is to pass Greentea reset_reason/watchdog_reset tests, which have e.g. 50~100 reset delay tolerance.
69+
*/
70+
#define NU_WDT_RESET_DELAY_RSTDSEL WDT_RESET_DELAY_130CLK
4871

4972
/* Support watchdog timeout values beyond H/W
5073
*
@@ -76,11 +99,19 @@ watchdog_status_t hal_watchdog_init(const watchdog_config_t *config)
7699
if (! wdt_hw_inited) {
77100
wdt_hw_inited = 1;
78101

102+
SYS_UnlockReg();
103+
79104
/* Enable IP module clock */
80105
CLK_EnableModuleClock(WDT_MODULE);
81106

82107
/* Select IP clock source */
108+
#if NU_INTERN_WDT_CLKSRC_SEL == NU_INTERN_WDT_CLKSRC_LXT
109+
CLK_SetModuleClock(WDT_MODULE, CLK_CLKSEL1_WDTSEL_LXT, 0);
110+
#elif NU_INTERN_WDT_CLKSRC_SEL == NU_INTERN_WDT_CLKSRC_LIRC
83111
CLK_SetModuleClock(WDT_MODULE, CLK_CLKSEL1_WDTSEL_LIRC, 0);
112+
#endif
113+
114+
SYS_LockReg();
84115

85116
/* Set up IP interrupt */
86117
NVIC_SetVector(WDT_IRQn, (uint32_t) WDT_IRQHandler);
@@ -125,9 +156,10 @@ watchdog_features_t hal_watchdog_get_platform_features(void)
125156
wdt_feat.update_config = 1;
126157
/* Support stopping watchdog timer */
127158
wdt_feat.disable_watchdog = 1;
128-
/* Accuracy of watchdog timer */
129-
wdt_feat.clock_typical_frequency = 10000;
130-
wdt_feat.clock_max_frequency = 15000;
159+
/* Typical frequency of not calibrated watchdog clock in Hz */
160+
wdt_feat.clock_typical_frequency = NU_WDTCLK_PER_SEC;
161+
/* Maximum frequency of not calibrated watchdog clock in Hz */
162+
wdt_feat.clock_max_frequency = NU_WDTCLK_PER_SEC_MAX;
131163

132164
return wdt_feat;
133165
}

targets/TARGET_NUVOTON/TARGET_M480/watchdog_api.c

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,30 @@
2222

2323
#include "cmsis.h"
2424

25-
/* Micro seconds per second */
26-
#define NU_US_PER_SEC 1000000
25+
/* Define WDT clock source in target configuration option */
26+
#ifndef MBED_CONF_TARGET_WDT_CLKSRC_SEL
27+
#define MBED_CONF_TARGET_WDT_CLKSRC_SEL LXT
28+
#endif
29+
30+
/* WDT clock source definition */
31+
#define NU_INTERN_WDT_CLKSRC_LXT 1
32+
#define NU_INTERN_WDT_CLKSRC_LIRC 2
33+
34+
/* WDT clock source selection */
35+
#define NU_INTERN_WDT_CLKSRC_SEL__(SEL) NU_INTERN_WDT_CLKSRC_##SEL
36+
#define NU_INTERN_WDT_CLKSRC_SEL_(SEL) NU_INTERN_WDT_CLKSRC_SEL__(SEL)
37+
#define NU_INTERN_WDT_CLKSRC_SEL NU_INTERN_WDT_CLKSRC_SEL_(MBED_CONF_TARGET_WDT_CLKSRC_SEL)
2738

2839
/* Watchdog clock per second */
40+
#if NU_INTERN_WDT_CLKSRC_SEL == NU_INTERN_WDT_CLKSRC_LXT
41+
#define NU_WDTCLK_PER_SEC (__LXT)
42+
#define NU_WDTCLK_PER_SEC_MAX (__LXT)
43+
#define NU_WDTCLK_PER_SEC_MIN (__LXT)
44+
#elif NU_INTERN_WDT_CLKSRC_SEL == NU_INTERN_WDT_CLKSRC_LIRC
2945
#define NU_WDTCLK_PER_SEC (__LIRC)
46+
#define NU_WDTCLK_PER_SEC_MAX ((uint32_t) ((__LIRC) * 2.0f))
47+
#define NU_WDTCLK_PER_SEC_MIN ((uint32_t) ((__LIRC) * 0.5f))
48+
#endif
3049

3150
/* Convert watchdog clock to nearest ms */
3251
#define NU_WDTCLK2MS(WDTCLK) (((WDTCLK) * 1000 + ((NU_WDTCLK_PER_SEC) / 2)) / (NU_WDTCLK_PER_SEC))
@@ -44,8 +63,12 @@
4463
#define NU_WDT_65536CLK 65536
4564
#define NU_WDT_262144CLK 262144
4665

47-
/* Watchdog reset delay */
48-
#define NU_WDT_RESET_DELAY_RSTDSEL WDT_RESET_DELAY_3CLK
66+
/* Watchdog reset delay
67+
*
68+
* 1. Cannot be too small. This is to avoid premature WDT reset in pieces of timeout cascading.
69+
* 2. Cannot be too large. This is to pass Greentea reset_reason/watchdog_reset tests, which have e.g. 50~100 reset delay tolerance.
70+
*/
71+
#define NU_WDT_RESET_DELAY_RSTDSEL WDT_RESET_DELAY_130CLK
4972

5073
/* Support watchdog timeout values beyond H/W
5174
*
@@ -77,11 +100,19 @@ watchdog_status_t hal_watchdog_init(const watchdog_config_t *config)
77100
if (! wdt_hw_inited) {
78101
wdt_hw_inited = 1;
79102

103+
SYS_UnlockReg();
104+
80105
/* Enable IP module clock */
81106
CLK_EnableModuleClock(WDT_MODULE);
82107

83108
/* Select IP clock source */
109+
#if NU_INTERN_WDT_CLKSRC_SEL == NU_INTERN_WDT_CLKSRC_LXT
110+
CLK_SetModuleClock(WDT_MODULE, CLK_CLKSEL1_WDTSEL_LXT, 0);
111+
#elif NU_INTERN_WDT_CLKSRC_SEL == NU_INTERN_WDT_CLKSRC_LIRC
84112
CLK_SetModuleClock(WDT_MODULE, CLK_CLKSEL1_WDTSEL_LIRC, 0);
113+
#endif
114+
115+
SYS_LockReg();
85116

86117
/* Set up IP interrupt */
87118
NVIC_SetVector(WDT_IRQn, (uint32_t) WDT_IRQHandler);
@@ -126,10 +157,10 @@ watchdog_features_t hal_watchdog_get_platform_features(void)
126157
wdt_feat.update_config = 1;
127158
/* Support stopping watchdog timer */
128159
wdt_feat.disable_watchdog = 1;
129-
/* Accuracy of watchdog timer */
130-
wdt_feat.clock_typical_frequency = 10000;
131-
wdt_feat.clock_max_frequency = 15000;
132-
160+
/* Typical frequency of not calibrated watchdog clock in Hz */
161+
wdt_feat.clock_typical_frequency = NU_WDTCLK_PER_SEC;
162+
/* Maximum frequency of not calibrated watchdog clock in Hz */
163+
wdt_feat.clock_max_frequency = NU_WDTCLK_PER_SEC_MAX;
133164

134165
return wdt_feat;
135166
}

targets/TARGET_NUVOTON/TARGET_NANO100/watchdog_api.c

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,31 @@
2020

2121
#include "cmsis.h"
2222

23-
/* Micro seconds per second */
24-
#define NU_US_PER_SEC 1000000
23+
/* Define WDT clock source in target configuration option */
24+
#ifndef MBED_CONF_TARGET_WDT_CLKSRC_SEL
25+
#define MBED_CONF_TARGET_WDT_CLKSRC_SEL LIRC
26+
#endif
27+
28+
/* WDT clock source definition */
29+
#define NU_INTERN_WDT_CLKSRC_LXT 1
30+
/* Not support LIRC clocked WDT */
31+
//#define NU_INTERN_WDT_CLKSRC_LIRC 2
32+
33+
/* WDT clock source selection */
34+
#define NU_INTERN_WDT_CLKSRC_SEL__(SEL) NU_INTERN_WDT_CLKSRC_##SEL
35+
#define NU_INTERN_WDT_CLKSRC_SEL_(SEL) NU_INTERN_WDT_CLKSRC_SEL__(SEL)
36+
#define NU_INTERN_WDT_CLKSRC_SEL NU_INTERN_WDT_CLKSRC_SEL_(MBED_CONF_TARGET_WDT_CLKSRC_SEL)
2537

2638
/* Watchdog clock per second */
39+
#if NU_INTERN_WDT_CLKSRC_SEL == NU_INTERN_WDT_CLKSRC_LXT
40+
#define NU_WDTCLK_PER_SEC (__LXT)
41+
#define NU_WDTCLK_PER_SEC_MAX (__LXT)
42+
#define NU_WDTCLK_PER_SEC_MIN (__LXT)
43+
#elif NU_INTERN_WDT_CLKSRC_SEL == NU_INTERN_WDT_CLKSRC_LIRC
2744
#define NU_WDTCLK_PER_SEC (__LIRC)
45+
#define NU_WDTCLK_PER_SEC_MAX ((uint32_t) ((__LIRC) * 1.5f))
46+
#define NU_WDTCLK_PER_SEC_MIN ((uint32_t) ((__LIRC) * 0.5f))
47+
#endif
2848

2949
/* Convert watchdog clock to nearest ms */
3050
#define NU_WDTCLK2MS(WDTCLK) (((WDTCLK) * 1000 + ((NU_WDTCLK_PER_SEC) / 2)) / (NU_WDTCLK_PER_SEC))
@@ -42,8 +62,12 @@
4262
#define NU_WDT_65536CLK 65536
4363
#define NU_WDT_262144CLK 262144
4464

45-
/* Watchdog reset delay */
46-
#define NU_WDT_RESET_DELAY_RSTDSEL WDT_RESET_DELAY_3CLK
65+
/* Watchdog reset delay
66+
*
67+
* 1. Cannot be too small. This is to avoid premature WDT reset in pieces of timeout cascading.
68+
* 2. Cannot be too large. This is to pass Greentea reset_reason/watchdog_reset tests, which have e.g. 50~100 reset delay tolerance.
69+
*/
70+
#define NU_WDT_RESET_DELAY_RSTDSEL WDT_RESET_DELAY_130CLK
4771

4872
/* Support watchdog timeout values beyond H/W
4973
*
@@ -77,12 +101,16 @@ watchdog_status_t hal_watchdog_init(const watchdog_config_t *config)
77101
if (! wdt_hw_inited) {
78102
wdt_hw_inited = 1;
79103

104+
SYS_UnlockReg();
105+
80106
/* Enable IP module clock */
81107
CLK_EnableModuleClock(WDT_MODULE);
82108

83109
/* Select IP clock source */
84110
CLK_SetModuleClock(WDT_MODULE, 0, 0);
85111

112+
SYS_LockReg();
113+
86114
/* Set up IP interrupt */
87115
NVIC_SetVector(WDT_IRQn, (uint32_t) WDT_IRQHandler);
88116
NVIC_EnableIRQ(WDT_IRQn);
@@ -130,9 +158,10 @@ watchdog_features_t hal_watchdog_get_platform_features(void)
130158
wdt_feat.update_config = 1;
131159
/* Support stopping watchdog timer */
132160
wdt_feat.disable_watchdog = 1;
133-
/* Accuracy of watchdog timer */
134-
wdt_feat.clock_typical_frequency = 10000;
135-
wdt_feat.clock_max_frequency = 15000;
161+
/* Typical frequency of not calibrated watchdog clock in Hz */
162+
wdt_feat.clock_typical_frequency = NU_WDTCLK_PER_SEC;
163+
/* Maximum frequency of not calibrated watchdog clock in Hz */
164+
wdt_feat.clock_max_frequency = NU_WDTCLK_PER_SEC_MAX;
136165

137166
return wdt_feat;
138167
}

targets/TARGET_NUVOTON/TARGET_NUC472/watchdog_api.c

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,30 @@
2020

2121
#include "cmsis.h"
2222

23-
/* Micro seconds per second */
24-
#define NU_US_PER_SEC 1000000
23+
/* Define WDT clock source in target configuration option */
24+
#ifndef MBED_CONF_TARGET_WDT_CLKSRC_SEL
25+
#define MBED_CONF_TARGET_WDT_CLKSRC_SEL LXT
26+
#endif
27+
28+
/* WDT clock source definition */
29+
#define NU_INTERN_WDT_CLKSRC_LXT 1
30+
#define NU_INTERN_WDT_CLKSRC_LIRC 2
31+
32+
/* WDT clock source selection */
33+
#define NU_INTERN_WDT_CLKSRC_SEL__(SEL) NU_INTERN_WDT_CLKSRC_##SEL
34+
#define NU_INTERN_WDT_CLKSRC_SEL_(SEL) NU_INTERN_WDT_CLKSRC_SEL__(SEL)
35+
#define NU_INTERN_WDT_CLKSRC_SEL NU_INTERN_WDT_CLKSRC_SEL_(MBED_CONF_TARGET_WDT_CLKSRC_SEL)
2536

2637
/* Watchdog clock per second */
38+
#if NU_INTERN_WDT_CLKSRC_SEL == NU_INTERN_WDT_CLKSRC_LXT
39+
#define NU_WDTCLK_PER_SEC (__LXT)
40+
#define NU_WDTCLK_PER_SEC_MAX (__LXT)
41+
#define NU_WDTCLK_PER_SEC_MIN (__LXT)
42+
#elif NU_INTERN_WDT_CLKSRC_SEL == NU_INTERN_WDT_CLKSRC_LIRC
2743
#define NU_WDTCLK_PER_SEC (__LIRC)
44+
#define NU_WDTCLK_PER_SEC_MAX ((uint32_t) ((__LIRC) * 1.4f))
45+
#define NU_WDTCLK_PER_SEC_MIN ((uint32_t) ((__LIRC) * 0.6f))
46+
#endif
2847

2948
/* Convert watchdog clock to nearest ms */
3049
#define NU_WDTCLK2MS(WDTCLK) (((WDTCLK) * 1000 + ((NU_WDTCLK_PER_SEC) / 2)) / (NU_WDTCLK_PER_SEC))
@@ -42,8 +61,12 @@
4261
#define NU_WDT_65536CLK 65536
4362
#define NU_WDT_262144CLK 262144
4463

45-
/* Watchdog reset delay */
46-
#define NU_WDT_RESET_DELAY_RSTDSEL WDT_RESET_DELAY_3CLK
64+
/* Watchdog reset delay
65+
*
66+
* 1. Cannot be too small. This is to avoid premature WDT reset in pieces of timeout cascading.
67+
* 2. Cannot be too large. This is to pass Greentea reset_reason/watchdog_reset tests, which have e.g. 50~100 reset delay tolerance.
68+
*/
69+
#define NU_WDT_RESET_DELAY_RSTDSEL WDT_RESET_DELAY_130CLK
4770

4871
/* Support watchdog timeout values beyond H/W
4972
*
@@ -75,11 +98,19 @@ watchdog_status_t hal_watchdog_init(const watchdog_config_t *config)
7598
if (! wdt_hw_inited) {
7699
wdt_hw_inited = 1;
77100

101+
SYS_UnlockReg();
102+
78103
/* Enable IP module clock */
79104
CLK_EnableModuleClock(WDT_MODULE);
80105

81106
/* Select IP clock source */
107+
#if NU_INTERN_WDT_CLKSRC_SEL == NU_INTERN_WDT_CLKSRC_LXT
108+
CLK_SetModuleClock(WDT_MODULE, CLK_CLKSEL1_WDTSEL_LXT, 0);
109+
#elif NU_INTERN_WDT_CLKSRC_SEL == NU_INTERN_WDT_CLKSRC_LIRC
82110
CLK_SetModuleClock(WDT_MODULE, CLK_CLKSEL1_WDTSEL_LIRC, 0);
111+
#endif
112+
113+
SYS_LockReg();
83114

84115
/* Set up IP interrupt */
85116
NVIC_SetVector(WDT_IRQn, (uint32_t) WDT_IRQHandler);
@@ -124,9 +155,10 @@ watchdog_features_t hal_watchdog_get_platform_features(void)
124155
wdt_feat.update_config = 1;
125156
/* Support stopping watchdog timer */
126157
wdt_feat.disable_watchdog = 1;
127-
/* Accuracy of watchdog timer */
128-
wdt_feat.clock_typical_frequency = 10000;
129-
wdt_feat.clock_max_frequency = 14000;
158+
/* Typical frequency of not calibrated watchdog clock in Hz */
159+
wdt_feat.clock_typical_frequency = NU_WDTCLK_PER_SEC;
160+
/* Maximum frequency of not calibrated watchdog clock in Hz */
161+
wdt_feat.clock_max_frequency = NU_WDTCLK_PER_SEC_MAX;
130162

131163
return wdt_feat;
132164
}

0 commit comments

Comments
 (0)