From a0c53896e08bbbd0584413ce705620434d03c7af Mon Sep 17 00:00:00 2001 From: Chun-Chieh Li Date: Mon, 17 May 2021 10:16:39 +0800 Subject: [PATCH] Nuvoton: Enable no HXT/LXT configurabiliy LXT/HXT are external crystl oscillator and can be absent on custom board. This enables configuring LXT/HXT presence: 1. By default, LXT/HXT are configured to be present, except M252 which has no HXT. 2. When LXT is configured to not present, lp_ticker/watchdog will clock by LIRC instead. 3. Limitations: (1) On all targets, LIRC-clocked lp_ticker gets inaccurate and fails to pass tests. (2) On NUC472/M453, HIRC-clocked PLL doesn't output 1MHz-aligned frequency. us_ticker gets slight inaccurate. (3) On all targets, LIRC-clocked RTC is not supported due to no H/W path/RTC clock source reset to LXT on reset/RTC not trimmed for other clock rates. 4. On M263, TRNG's clock source defaults to LXT and needs special handling without LXT. 5. On M252, replace target.hxt-enable with target.hxt-present for consistency. --- .../TARGET_M251/device/system_M251.h | 4 + .../TARGET_NUVOTON/TARGET_M251/lp_ticker.c | 8 ++ .../TARGET_M251/mbed_overrides.c | 20 +++-- targets/TARGET_NUVOTON/TARGET_M251/rtc_api.c | 8 ++ .../TARGET_NUVOTON/TARGET_M261/lp_ticker.c | 8 ++ .../TARGET_M261/mbed_overrides.c | 12 ++- targets/TARGET_NUVOTON/TARGET_M261/rtc_api.c | 18 +++++ .../TARGET_NUVOTON/TARGET_M261/trng_api.cpp | 19 +++++ .../TARGET_M451/device/startup_M451Series.c | 6 +- .../TARGET_M451/device/system_M451Series.c | 2 + .../TARGET_M451/device/system_M451Series.h | 4 + .../TARGET_NUVOTON/TARGET_M451/lp_ticker.c | 8 ++ .../TARGET_M451/mbed_overrides.c | 12 ++- targets/TARGET_NUVOTON/TARGET_M451/rtc_api.c | 18 +++++ .../TARGET_NUVOTON/TARGET_M451/us_ticker.c | 6 ++ .../TARGET_NUVOTON/TARGET_M451/watchdog_api.c | 22 +----- .../TARGET_M480/device/system_M480.c | 4 + .../TARGET_NUVOTON/TARGET_M480/lp_ticker.c | 8 ++ .../TARGET_M480/mbed_overrides.c | 12 ++- targets/TARGET_NUVOTON/TARGET_M480/rtc_api.c | 18 +++++ .../TARGET_NUVOTON/TARGET_M480/watchdog_api.c | 22 +----- .../TARGET_NUVOTON/TARGET_NANO100/lp_ticker.c | 8 ++ .../TARGET_NANO100/mbed_overrides.c | 22 +++++- .../TARGET_NUVOTON/TARGET_NANO100/rtc_api.c | 8 ++ .../TARGET_NUVOTON/TARGET_NANO100/us_ticker.c | 4 + .../TARGET_NANO100/watchdog_api.c | 21 +----- .../TARGET_NUVOTON/TARGET_NUC472/lp_ticker.c | 8 ++ .../TARGET_NUC472/mbed_overrides.c | 27 +++++-- .../TARGET_NUVOTON/TARGET_NUC472/rtc_api.c | 8 ++ .../TARGET_NUVOTON/TARGET_NUC472/us_ticker.c | 6 ++ .../TARGET_NUC472/watchdog_api.c | 22 +----- targets/targets.json | 74 +++++++++++++++++++ 32 files changed, 348 insertions(+), 99 deletions(-) diff --git a/targets/TARGET_NUVOTON/TARGET_M251/device/system_M251.h b/targets/TARGET_NUVOTON/TARGET_M251/device/system_M251.h index f15db1a9e1..a39a96dc7c 100644 --- a/targets/TARGET_NUVOTON/TARGET_M251/device/system_M251.h +++ b/targets/TARGET_NUVOTON/TARGET_M251/device/system_M251.h @@ -50,7 +50,11 @@ extern "C" { #define __HSI (48000000UL) /*!< PLL default output is 48MHz */ #define __SYS_OSC_CLK ( ___HSI) /*!< Main oscillator frequency */ +#if MBED_CONF_TARGET_HXT_PRESENT #define __SYSTEM_CLOCK (1UL*__HXT) +#else +#define __SYSTEM_CLOCK (1UL*__HIRC) +#endif extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ extern uint32_t CyclesPerUs; /*!< Cycles per micro second */ diff --git a/targets/TARGET_NUVOTON/TARGET_M251/lp_ticker.c b/targets/TARGET_NUVOTON/TARGET_M251/lp_ticker.c index c05d1054ba..5845b8d2e3 100644 --- a/targets/TARGET_NUVOTON/TARGET_M251/lp_ticker.c +++ b/targets/TARGET_NUVOTON/TARGET_M251/lp_ticker.c @@ -31,7 +31,11 @@ /* Timer clock per lp_ticker tick */ #define NU_TMRCLK_PER_TICK 1 /* Timer clock per second */ +#if MBED_CONF_TARGET_LXT_PRESENT #define NU_TMRCLK_PER_SEC (__LXT) +#else +#define NU_TMRCLK_PER_SEC (__LIRC) +#endif /* Timer max counter bit size */ #define NU_TMR_MAXCNT_BITSIZE 24 /* Timer max counter */ @@ -40,7 +44,11 @@ static void tmr1_vec(void); /* NOTE: To wake the system from power down mode, timer clock source must be ether LXT or LIRC. */ +#if MBED_CONF_TARGET_LXT_PRESENT static const struct nu_modinit_s timer1_modinit = {TIMER_1, TMR1_MODULE, CLK_CLKSEL1_TMR1SEL_LXT, 0, TMR1_RST, TMR1_IRQn, (void *) tmr1_vec}; +#else +static const struct nu_modinit_s timer1_modinit = {TIMER_1, TMR1_MODULE, CLK_CLKSEL1_TMR1SEL_LIRC, 0, TMR1_RST, TMR1_IRQn, (void *) tmr1_vec}; +#endif #define TIMER_MODINIT timer1_modinit diff --git a/targets/TARGET_NUVOTON/TARGET_M251/mbed_overrides.c b/targets/TARGET_NUVOTON/TARGET_M251/mbed_overrides.c index b7a0af1002..85fddf7ffb 100644 --- a/targets/TARGET_NUVOTON/TARGET_M251/mbed_overrides.c +++ b/targets/TARGET_NUVOTON/TARGET_M251/mbed_overrides.c @@ -33,47 +33,55 @@ void mbed_sdk_init(void) /* Unlock protected registers */ SYS_UnlockReg(); -#if defined(NU_HXT_ENABLE) && (NU_HXT_ENABLE == 1UL) +#if MBED_CONF_TARGET_HXT_PRESENT /* HXT Enable: Set XT1_OUT(PF.2) and XT1_IN(PF.3) to input mode */ PF->MODE &= ~(GPIO_MODE_MODE2_Msk | GPIO_MODE_MODE3_Msk); #endif +#if MBED_CONF_TARGET_LXT_PRESENT /* LXT Enable: Set X32_OUT(PF.4) and X32_IN(PF.5) to input mode */ PF->MODE &= ~(GPIO_MODE_MODE4_Msk | GPIO_MODE_MODE5_Msk); +#endif /* Enable HIRC clock (Internal RC 48MHz) */ CLK_EnableXtalRC(CLK_PWRCTL_HIRCEN_Msk); -#if defined(NU_HXT_ENABLE) && (NU_HXT_ENABLE == 1UL) +#if MBED_CONF_TARGET_HXT_PRESENT /* Enable HXT clock (external XTAL 12MHz) */ CLK_EnableXtalRC(CLK_PWRCTL_HXTEN_Msk); #endif - /* Enable LIRC for lp_ticker */ + /* Enable LIRC */ CLK_EnableXtalRC(CLK_PWRCTL_LIRCEN_Msk); - /* Enable LXT for RTC */ +#if MBED_CONF_TARGET_LXT_PRESENT + /* Enable LXT */ CLK_EnableXtalRC(CLK_PWRCTL_LXTEN_Msk); +#endif /* Wait for HIRC clock ready */ CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk); -#if defined(NU_HXT_ENABLE) && (NU_HXT_ENABLE == 1UL) +#if MBED_CONF_TARGET_HXT_PRESENT /* Wait for HXT clock ready */ CLK_WaitClockReady(CLK_STATUS_HXTSTB_Msk); #endif /* Wait for LIRC clock ready */ CLK_WaitClockReady(CLK_STATUS_LIRCSTB_Msk); +#if MBED_CONF_TARGET_LXT_PRESENT /* Wait for LXT clock ready */ CLK_WaitClockReady(CLK_STATUS_LXTSTB_Msk); +#endif -#if defined(NU_HXT_ENABLE) && (NU_HXT_ENABLE == 1UL) +#if MBED_CONF_TARGET_HXT_PRESENT /* HXT Enable: Disable digital input path of analog pin XT1_OUT to prevent leakage */ GPIO_DISABLE_DIGITAL_PATH(PF, (1ul << 2)); /* HXT Enable: Disable digital input path of analog pin XT1_IN to prevent leakage */ GPIO_DISABLE_DIGITAL_PATH(PF, (1ul << 3)); #endif +#if MBED_CONF_TARGET_LXT_PRESENT /* LXT Enable: Disable digital input path of analog pin X32_OUT to prevent leakage */ GPIO_DISABLE_DIGITAL_PATH(PF, (1ul << 4)); /* LXT Enable: Disable digital input path of analog pin XT32_IN to prevent leakage */ GPIO_DISABLE_DIGITAL_PATH(PF, (1ul << 5)); +#endif /* Select HCLK clock source as HIRC and HCLK clock divider as 1 */ CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_HIRC, CLK_CLKDIV0_HCLK(1)); diff --git a/targets/TARGET_NUVOTON/TARGET_M251/rtc_api.c b/targets/TARGET_NUVOTON/TARGET_M251/rtc_api.c index 3a06977b3f..5039db5b77 100644 --- a/targets/TARGET_NUVOTON/TARGET_M251/rtc_api.c +++ b/targets/TARGET_NUVOTON/TARGET_M251/rtc_api.c @@ -26,6 +26,14 @@ #include "nu_miscutil.h" #include "mbed_mktime.h" +/* Not support LIRC-clocked RTC + * + * H/W doesn't support this path. + */ +#if !MBED_CONF_TARGET_LXT_PRESENT +#error "RTC can only clock by LXT but LXT is not present. Try disabling RTC by \"device_has_remove\" in mbed_app.json" +#endif + /* Micro seconds per second */ #define NU_US_PER_SEC 1000000 /* Timer clock per second diff --git a/targets/TARGET_NUVOTON/TARGET_M261/lp_ticker.c b/targets/TARGET_NUVOTON/TARGET_M261/lp_ticker.c index 379b3ef7da..f51df377f2 100644 --- a/targets/TARGET_NUVOTON/TARGET_M261/lp_ticker.c +++ b/targets/TARGET_NUVOTON/TARGET_M261/lp_ticker.c @@ -30,7 +30,11 @@ /* Timer clock per lp_ticker tick */ #define NU_TMRCLK_PER_TICK 1 /* Timer clock per second */ +#if MBED_CONF_TARGET_LXT_PRESENT #define NU_TMRCLK_PER_SEC (__LXT) +#else +#define NU_TMRCLK_PER_SEC (__LIRC) +#endif /* Timer max counter bit size */ #define NU_TMR_MAXCNT_BITSIZE 24 /* Timer max counter */ @@ -40,7 +44,11 @@ static void tmr1_vec(void); /* NOTE: To wake the system from power down mode, timer clock source must be ether LXT or LIRC. */ +#if MBED_CONF_TARGET_LXT_PRESENT static const struct nu_modinit_s timer1_modinit = {TIMER_1, TMR1_MODULE, CLK_CLKSEL1_TMR1SEL_LXT, 0, TMR1_RST, TMR1_IRQn, (void *) tmr1_vec}; +#else +static const struct nu_modinit_s timer1_modinit = {TIMER_1, TMR1_MODULE, CLK_CLKSEL1_TMR1SEL_LIRC, 0, TMR1_RST, TMR1_IRQn, (void *) tmr1_vec}; +#endif #define TIMER_MODINIT timer1_modinit diff --git a/targets/TARGET_NUVOTON/TARGET_M261/mbed_overrides.c b/targets/TARGET_NUVOTON/TARGET_M261/mbed_overrides.c index e29c3397e5..3d988ce8bb 100644 --- a/targets/TARGET_NUVOTON/TARGET_M261/mbed_overrides.c +++ b/targets/TARGET_NUVOTON/TARGET_M261/mbed_overrides.c @@ -36,23 +36,31 @@ void mbed_sdk_init(void) /* Enable HIRC clock (Internal RC 12MHz) */ CLK_EnableXtalRC(CLK_PWRCTL_HIRCEN_Msk); +#if MBED_CONF_TARGET_HXT_PRESENT /* Enable HXT clock (external XTAL 12MHz) */ CLK_EnableXtalRC(CLK_PWRCTL_HXTEN_Msk); - /* Enable LIRC for lp_ticker */ +#endif + /* Enable LIRC */ CLK_EnableXtalRC(CLK_PWRCTL_LIRCEN_Msk); - /* Enable LXT for RTC */ +#if MBED_CONF_TARGET_LXT_PRESENT + /* Enable LXT */ CLK_EnableXtalRC(CLK_PWRCTL_LXTEN_Msk); +#endif /* Enable HIRC48 clock (Internal RC 48MHz) */ CLK_EnableXtalRC(CLK_PWRCTL_HIRC48EN_Msk); /* Wait for HIRC clock ready */ CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk); +#if MBED_CONF_TARGET_HXT_PRESENT /* Wait for HXT clock ready */ CLK_WaitClockReady(CLK_STATUS_HXTSTB_Msk); +#endif /* Wait for LIRC clock ready */ CLK_WaitClockReady(CLK_STATUS_LIRCSTB_Msk); +#if MBED_CONF_TARGET_LXT_PRESENT /* Wait for LXT clock ready */ CLK_WaitClockReady(CLK_STATUS_LXTSTB_Msk); +#endif /* Wait for HIRC48 clock ready */ CLK_WaitClockReady(CLK_STATUS_HIRC48STB_Msk); diff --git a/targets/TARGET_NUVOTON/TARGET_M261/rtc_api.c b/targets/TARGET_NUVOTON/TARGET_M261/rtc_api.c index a0fc30a322..594a8be853 100644 --- a/targets/TARGET_NUVOTON/TARGET_M261/rtc_api.c +++ b/targets/TARGET_NUVOTON/TARGET_M261/rtc_api.c @@ -25,13 +25,27 @@ #include "nu_miscutil.h" #include "mbed_mktime.h" +/* Not support LIRC-clocked RTC + * + * Though H/W supports this path, it is still not supported because: + * 1. RTC is trimmed only for 32.768 KHz LXT, not for other clock rates. + * 2. RTC's clock source will reset to default LXT on reset. This results in rtc_reset test failing. + */ +#if !MBED_CONF_TARGET_LXT_PRESENT +#error "RTC can only clock by LXT but LXT is not present. Try disabling RTC by \"device_has_remove\" in mbed_app.json" +#endif + /* Micro seconds per second */ #define NU_US_PER_SEC 1000000 /* Timer clock per second * * NOTE: This dependents on real hardware. */ +#if MBED_CONF_TARGET_LXT_PRESENT #define NU_RTCCLK_PER_SEC __LXT +#else +#define NU_RTCCLK_PER_SEC __LIRC +#endif /* Strategy for implementation of RTC HAL * @@ -85,7 +99,11 @@ static time_t t_write = 0; /* Convert date time from H/W RTC to struct TM */ static void rtc_convert_datetime_hwrtc_to_tm(struct tm *datetime_tm, const S_RTC_TIME_DATA_T *datetime_hwrtc); +#if MBED_CONF_TARGET_LXT_PRESENT static const struct nu_modinit_s rtc_modinit = {RTC_0, RTC_MODULE, CLK_CLKSEL3_RTCSEL_LXT, 0, 0, RTC_IRQn, NULL}; +#else +static const struct nu_modinit_s rtc_modinit = {RTC_0, RTC_MODULE, CLK_CLKSEL3_RTCSEL_LIRC, 0, 0, RTC_IRQn, NULL}; +#endif void rtc_init(void) { diff --git a/targets/TARGET_NUVOTON/TARGET_M261/trng_api.cpp b/targets/TARGET_NUVOTON/TARGET_M261/trng_api.cpp index 18e928851a..cc5852646e 100644 --- a/targets/TARGET_NUVOTON/TARGET_M261/trng_api.cpp +++ b/targets/TARGET_NUVOTON/TARGET_M261/trng_api.cpp @@ -48,6 +48,25 @@ void trng_init(MBED_UNUSED trng_t *obj) /* Reset IP */ SYS_ResetModule(trng_modinit.rsetidx); +#if MBED_CONF_TARGET_LXT_PRESENT + /* 32K clock from (external) LXT */ +#else + /* 32K clock from LIRC32 */ + + /* Unlock protected registers */ + SYS_UnlockReg(); + + /* To access RTC registers, clock must be enabled first. */ + CLK_EnableModuleClock(RTC_MODULE); + + /* Enable 32K clock from LIRC32 */ + RTC->LXTCTL |= (RTC_LXTCTL_C32KS_Msk | RTC_LXTCTL_LIRC32KEN_Msk); + CLK_WaitClockReady(CLK_STATUS_LIRC32STB_Msk | CLK_STATUS_LXTSTB_Msk); + + /* Lock protected registers */ + SYS_LockReg(); +#endif + TRNG_T *trng_base = (TRNG_T *) NU_MODBASE(trng_modinit.modname); trng_base->ACT |= TRNG_ACT_ACT_Msk; diff --git a/targets/TARGET_NUVOTON/TARGET_M451/device/startup_M451Series.c b/targets/TARGET_NUVOTON/TARGET_M451/device/startup_M451Series.c index 67b0bd98c2..3f54444075 100644 --- a/targets/TARGET_NUVOTON/TARGET_M451/device/startup_M451Series.c +++ b/targets/TARGET_NUVOTON/TARGET_M451/device/startup_M451Series.c @@ -265,10 +265,12 @@ void Reset_Handler(void) /* Disable Power-on Reset function */ SYS_DISABLE_POR(); - + +#if MBED_CONF_TARGET_HXT_PRESENT /* HXT Crystal Type Select: INV */ CLK->PWRCTL &= ~CLK_PWRCTL_HXTSELTYP_Msk; - +#endif + /** * NOTE 1: Unlock is required for perhaps some register access in SystemInit(). * NOTE 2: Because EBI (external SRAM) init is done in SystemInit(), SystemInit() must be called at the very start. diff --git a/targets/TARGET_NUVOTON/TARGET_M451/device/system_M451Series.c b/targets/TARGET_NUVOTON/TARGET_M451/device/system_M451Series.c index df23aec568..8130c774a9 100644 --- a/targets/TARGET_NUVOTON/TARGET_M451/device/system_M451Series.c +++ b/targets/TARGET_NUVOTON/TARGET_M451/device/system_M451Series.c @@ -84,8 +84,10 @@ void SystemInit(void) { M32(GCR_BASE+0x14) |= BIT7; } +#if MBED_CONF_TARGET_HXT_PRESENT /* Force to use INV type with HXT */ CLK->PWRCTL &= ~CLK_PWRCTL_HXTSELTYP_Msk; +#endif SYS_LockReg(); diff --git a/targets/TARGET_NUVOTON/TARGET_M451/device/system_M451Series.h b/targets/TARGET_NUVOTON/TARGET_M451/device/system_M451Series.h index edb80e509a..4c944ed08a 100644 --- a/targets/TARGET_NUVOTON/TARGET_M451/device/system_M451Series.h +++ b/targets/TARGET_NUVOTON/TARGET_M451/device/system_M451Series.h @@ -38,7 +38,11 @@ extern "C" { #define __SYS_OSC_CLK ( ___HSI) /* Main oscillator frequency */ +#if MBED_CONF_TARGET_HXT_PRESENT #define __SYSTEM_CLOCK (1*__HXT) +#else +#define __SYSTEM_CLOCK (1*__HIRC) +#endif extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ extern uint32_t CyclesPerUs; /*!< Cycles per micro second */ diff --git a/targets/TARGET_NUVOTON/TARGET_M451/lp_ticker.c b/targets/TARGET_NUVOTON/TARGET_M451/lp_ticker.c index 1f5079668d..10b1ee2469 100644 --- a/targets/TARGET_NUVOTON/TARGET_M451/lp_ticker.c +++ b/targets/TARGET_NUVOTON/TARGET_M451/lp_ticker.c @@ -29,7 +29,11 @@ /* Timer clock per lp_ticker tick */ #define NU_TMRCLK_PER_TICK 1 /* Timer clock per second */ +#if MBED_CONF_TARGET_LXT_PRESENT #define NU_TMRCLK_PER_SEC (__LXT) +#else +#define NU_TMRCLK_PER_SEC (__LIRC) +#endif /* Timer max counter bit size */ #define NU_TMR_MAXCNT_BITSIZE 24 /* Timer max counter */ @@ -38,7 +42,11 @@ static void tmr1_vec(void); /* NOTE: To wake the system from power down mode, timer clock source must be ether LXT or LIRC. */ +#if MBED_CONF_TARGET_LXT_PRESENT static const struct nu_modinit_s timer1_modinit = {TIMER_1, TMR1_MODULE, CLK_CLKSEL1_TMR1SEL_LXT, 0, TMR1_RST, TMR1_IRQn, (void *) tmr1_vec}; +#else +static const struct nu_modinit_s timer1_modinit = {TIMER_1, TMR1_MODULE, CLK_CLKSEL1_TMR1SEL_LIRC, 0, TMR1_RST, TMR1_IRQn, (void *) tmr1_vec}; +#endif #define TIMER_MODINIT timer1_modinit diff --git a/targets/TARGET_NUVOTON/TARGET_M451/mbed_overrides.c b/targets/TARGET_NUVOTON/TARGET_M451/mbed_overrides.c index d98873577d..7e9a231eb5 100644 --- a/targets/TARGET_NUVOTON/TARGET_M451/mbed_overrides.c +++ b/targets/TARGET_NUVOTON/TARGET_M451/mbed_overrides.c @@ -33,21 +33,29 @@ void mbed_sdk_init(void) /* Enable HIRC clock (Internal RC 22.1184MHz) */ CLK_EnableXtalRC(CLK_PWRCTL_HIRCEN_Msk); +#if MBED_CONF_TARGET_HXT_PRESENT /* Enable HXT clock (external XTAL 12MHz) */ CLK_EnableXtalRC(CLK_PWRCTL_HXTEN_Msk); - /* Enable LIRC for lp_ticker */ +#endif + /* Enable LIRC */ CLK_EnableXtalRC(CLK_PWRCTL_LIRCEN_Msk); - /* Enable LXT for RTC */ +#if MBED_CONF_TARGET_LXT_PRESENT + /* Enable LXT */ CLK_EnableXtalRC(CLK_PWRCTL_LXTEN_Msk); +#endif /* Wait for HIRC clock ready */ CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk); +#if MBED_CONF_TARGET_HXT_PRESENT /* Wait for HXT clock ready */ CLK_WaitClockReady(CLK_STATUS_HXTSTB_Msk); +#endif /* Wait for LIRC clock ready */ CLK_WaitClockReady(CLK_STATUS_LIRCSTB_Msk); +#if MBED_CONF_TARGET_LXT_PRESENT /* Wait for LXT clock ready */ CLK_WaitClockReady(CLK_STATUS_LXTSTB_Msk); +#endif /* Select HCLK clock source as HIRC and HCLK clock divider as 1 */ CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_HIRC, CLK_CLKDIV0_HCLK(1)); diff --git a/targets/TARGET_NUVOTON/TARGET_M451/rtc_api.c b/targets/TARGET_NUVOTON/TARGET_M451/rtc_api.c index 5c034c179d..b026d52334 100644 --- a/targets/TARGET_NUVOTON/TARGET_M451/rtc_api.c +++ b/targets/TARGET_NUVOTON/TARGET_M451/rtc_api.c @@ -24,13 +24,27 @@ #include "nu_miscutil.h" #include "mbed_mktime.h" +/* Not support LIRC-clocked RTC + * + * Though H/W supports this path, it is still not supported because: + * 1. RTC is trimmed only for 32.768 KHz LXT, not for other clock rates. + * 2. RTC's clock source will reset to default LXT on reset. This results in rtc_reset test failing. + */ +#if !MBED_CONF_TARGET_LXT_PRESENT +#error "RTC can only clock by LXT but LXT is not present. Try disabling RTC by \"device_has_remove\" in mbed_app.json" +#endif + /* Micro seconds per second */ #define NU_US_PER_SEC 1000000 /* Timer clock per second * * NOTE: This dependents on real hardware. */ +#if MBED_CONF_TARGET_LXT_PRESENT #define NU_RTCCLK_PER_SEC __LXT +#else +#define NU_RTCCLK_PER_SEC __LIRC +#endif /* Strategy for implementation of RTC HAL * @@ -84,7 +98,11 @@ static time_t t_write = 0; /* Convert date time from H/W RTC to struct TM */ static void rtc_convert_datetime_hwrtc_to_tm(struct tm *datetime_tm, const S_RTC_TIME_DATA_T *datetime_hwrtc); +#if MBED_CONF_TARGET_LXT_PRESENT static const struct nu_modinit_s rtc_modinit = {RTC_0, RTC_MODULE, CLK_CLKSEL3_RTCSEL_LXT, 0, 0, RTC_IRQn, NULL}; +#else +static const struct nu_modinit_s rtc_modinit = {RTC_0, RTC_MODULE, CLK_CLKSEL3_RTCSEL_LIRC, 0, 0, RTC_IRQn, NULL}; +#endif void rtc_init(void) { diff --git a/targets/TARGET_NUVOTON/TARGET_M451/us_ticker.c b/targets/TARGET_NUVOTON/TARGET_M451/us_ticker.c index 3b4f228b78..bf7cd866ce 100644 --- a/targets/TARGET_NUVOTON/TARGET_M451/us_ticker.c +++ b/targets/TARGET_NUVOTON/TARGET_M451/us_ticker.c @@ -71,7 +71,13 @@ void us_ticker_init(void) uint32_t clk_timer = TIMER_GetModuleClock(timer_base); uint32_t prescale_timer = clk_timer / NU_TMRCLK_PER_SEC - 1; MBED_ASSERT((prescale_timer != (uint32_t) -1) && prescale_timer <= 127); + /* HIRC-clocked PLL fails to output 1MHz-aligned frequency + * + * PLL, clocked by HIRC instead of HXT, doesn't output 1MHz-aligned frequency. + */ +#if MBED_CONF_TARGET_HXT_PRESENT MBED_ASSERT((clk_timer % NU_TMRCLK_PER_SEC) == 0); +#endif uint32_t cmp_timer = TMR_CMP_MAX; MBED_ASSERT(cmp_timer >= TMR_CMP_MIN && cmp_timer <= TMR_CMP_MAX); // NOTE: TIMER_CTL_CNTDATEN_Msk exists in NUC472, but not in M451. In M451, TIMER_CNT is updated continuously by default. diff --git a/targets/TARGET_NUVOTON/TARGET_M451/watchdog_api.c b/targets/TARGET_NUVOTON/TARGET_M451/watchdog_api.c index 5b8d459d87..aaa60b15d2 100644 --- a/targets/TARGET_NUVOTON/TARGET_M451/watchdog_api.c +++ b/targets/TARGET_NUVOTON/TARGET_M451/watchdog_api.c @@ -21,26 +21,12 @@ #include "cmsis.h" -/* Define WDT clock source in target configuration option */ -#ifndef MBED_CONF_TARGET_WDT_CLKSRC_SEL -#define MBED_CONF_TARGET_WDT_CLKSRC_SEL LXT -#endif - -/* WDT clock source definition */ -#define NU_INTERN_WDT_CLKSRC_LXT 1 -#define NU_INTERN_WDT_CLKSRC_LIRC 2 - -/* WDT clock source selection */ -#define NU_INTERN_WDT_CLKSRC_SEL__(SEL) NU_INTERN_WDT_CLKSRC_##SEL -#define NU_INTERN_WDT_CLKSRC_SEL_(SEL) NU_INTERN_WDT_CLKSRC_SEL__(SEL) -#define NU_INTERN_WDT_CLKSRC_SEL NU_INTERN_WDT_CLKSRC_SEL_(MBED_CONF_TARGET_WDT_CLKSRC_SEL) - /* Watchdog clock per second */ -#if NU_INTERN_WDT_CLKSRC_SEL == NU_INTERN_WDT_CLKSRC_LXT +#if MBED_CONF_TARGET_LXT_PRESENT #define NU_WDTCLK_PER_SEC (__LXT) #define NU_WDTCLK_PER_SEC_MAX (__LXT) #define NU_WDTCLK_PER_SEC_MIN (__LXT) -#elif NU_INTERN_WDT_CLKSRC_SEL == NU_INTERN_WDT_CLKSRC_LIRC +#else #define NU_WDTCLK_PER_SEC (__LIRC) #define NU_WDTCLK_PER_SEC_MAX ((uint32_t) ((__LIRC) * 1.5f)) #define NU_WDTCLK_PER_SEC_MIN ((uint32_t) ((__LIRC) * 0.5f)) @@ -105,9 +91,9 @@ watchdog_status_t hal_watchdog_init(const watchdog_config_t *config) CLK_EnableModuleClock(WDT_MODULE); /* Select IP clock source */ -#if NU_INTERN_WDT_CLKSRC_SEL == NU_INTERN_WDT_CLKSRC_LXT +#if MBED_CONF_TARGET_LXT_PRESENT CLK_SetModuleClock(WDT_MODULE, CLK_CLKSEL1_WDTSEL_LXT, 0); -#elif NU_INTERN_WDT_CLKSRC_SEL == NU_INTERN_WDT_CLKSRC_LIRC +#else CLK_SetModuleClock(WDT_MODULE, CLK_CLKSEL1_WDTSEL_LIRC, 0); #endif diff --git a/targets/TARGET_NUVOTON/TARGET_M480/device/system_M480.c b/targets/TARGET_NUVOTON/TARGET_M480/device/system_M480.c index 8bff1dc705..0ff7c7addb 100644 --- a/targets/TARGET_NUVOTON/TARGET_M480/device/system_M480.c +++ b/targets/TARGET_NUVOTON/TARGET_M480/device/system_M480.c @@ -60,6 +60,7 @@ void SystemCoreClockUpdate (void) /* Get Core Clock Frequency */ CyclesPerUs = (SystemCoreClock + 500000UL) / 1000000UL; } +#if MBED_CONF_TARGET_HXT_PRESENT /** * @brief Set PF.2 and PF.3 to input mode * @param None @@ -73,6 +74,7 @@ static __INLINE void HXTInit(void) PF->MODE &= ~(GPIO_MODE_MODE2_Msk | GPIO_MODE_MODE3_Msk); } +#endif /** * @brief Initialize the System @@ -106,7 +108,9 @@ void SystemInit (void) RTC->GPIOCTL1 &= ~(RTC_GPIOCTL1_CTLSEL4_Msk | RTC_GPIOCTL1_CTLSEL5_Msk | RTC_GPIOCTL1_CTLSEL6_Msk | RTC_GPIOCTL1_CTLSEL7_Msk); CLK->APBCLK0 &= ~CLK_APBCLK0_RTCCKEN_Msk; +#if MBED_CONF_TARGET_HXT_PRESENT HXTInit(); +#endif #if MBED_CONF_TARGET_SPIM_CCM_ENABLE // Divert SRAM bank2 (32 KB) to CCM from SPIM cache diff --git a/targets/TARGET_NUVOTON/TARGET_M480/lp_ticker.c b/targets/TARGET_NUVOTON/TARGET_M480/lp_ticker.c index 56aa796de2..e6bc5e2ba2 100644 --- a/targets/TARGET_NUVOTON/TARGET_M480/lp_ticker.c +++ b/targets/TARGET_NUVOTON/TARGET_M480/lp_ticker.c @@ -31,7 +31,11 @@ /* Timer clock per lp_ticker tick */ #define NU_TMRCLK_PER_TICK 1 /* Timer clock per second */ +#if MBED_CONF_TARGET_LXT_PRESENT #define NU_TMRCLK_PER_SEC (__LXT) +#else +#define NU_TMRCLK_PER_SEC (__LIRC) +#endif /* Timer max counter bit size */ #define NU_TMR_MAXCNT_BITSIZE 24 /* Timer max counter */ @@ -40,7 +44,11 @@ static void tmr1_vec(void); /* NOTE: To wake the system from power down mode, timer clock source must be ether LXT or LIRC. */ +#if MBED_CONF_TARGET_LXT_PRESENT static const struct nu_modinit_s timer1_modinit = {TIMER_1, TMR1_MODULE, CLK_CLKSEL1_TMR1SEL_LXT, 0, TMR1_RST, TMR1_IRQn, (void *) tmr1_vec}; +#else +static const struct nu_modinit_s timer1_modinit = {TIMER_1, TMR1_MODULE, CLK_CLKSEL1_TMR1SEL_LIRC, 0, TMR1_RST, TMR1_IRQn, (void *) tmr1_vec}; +#endif #define TIMER_MODINIT timer1_modinit diff --git a/targets/TARGET_NUVOTON/TARGET_M480/mbed_overrides.c b/targets/TARGET_NUVOTON/TARGET_M480/mbed_overrides.c index a6db2db539..ca21d76fb6 100644 --- a/targets/TARGET_NUVOTON/TARGET_M480/mbed_overrides.c +++ b/targets/TARGET_NUVOTON/TARGET_M480/mbed_overrides.c @@ -35,21 +35,29 @@ void mbed_sdk_init(void) /* Enable HIRC clock (Internal RC 22.1184MHz) */ CLK_EnableXtalRC(CLK_PWRCTL_HIRCEN_Msk); +#if MBED_CONF_TARGET_HXT_PRESENT /* Enable HXT clock (external XTAL 12MHz) */ CLK_EnableXtalRC(CLK_PWRCTL_HXTEN_Msk); - /* Enable LIRC for lp_ticker */ +#endif + /* Enable LIRC */ CLK_EnableXtalRC(CLK_PWRCTL_LIRCEN_Msk); - /* Enable LXT for RTC */ +#if MBED_CONF_TARGET_LXT_PRESENT + /* Enable LXT */ CLK_EnableXtalRC(CLK_PWRCTL_LXTEN_Msk); +#endif /* Wait for HIRC clock ready */ CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk); +#if MBED_CONF_TARGET_HXT_PRESENT /* Wait for HXT clock ready */ CLK_WaitClockReady(CLK_STATUS_HXTSTB_Msk); +#endif /* Wait for LIRC clock ready */ CLK_WaitClockReady(CLK_STATUS_LIRCSTB_Msk); +#if MBED_CONF_TARGET_LXT_PRESENT /* Wait for LXT clock ready */ CLK_WaitClockReady(CLK_STATUS_LXTSTB_Msk); +#endif /* Select HCLK clock source as HIRC and HCLK clock divider as 1 */ CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_HIRC, CLK_CLKDIV0_HCLK(1)); diff --git a/targets/TARGET_NUVOTON/TARGET_M480/rtc_api.c b/targets/TARGET_NUVOTON/TARGET_M480/rtc_api.c index 92f49376db..6488c8f1d1 100644 --- a/targets/TARGET_NUVOTON/TARGET_M480/rtc_api.c +++ b/targets/TARGET_NUVOTON/TARGET_M480/rtc_api.c @@ -26,13 +26,27 @@ #include "nu_miscutil.h" #include "mbed_mktime.h" +/* Not support LIRC-clocked RTC + * + * Though H/W supports this path, it is still not supported because: + * 1. RTC is trimmed only for 32.768 KHz LXT, not for other clock rates. + * 2. RTC's clock source will reset to default LXT on reset. This results in rtc_reset test failing. + */ +#if !MBED_CONF_TARGET_LXT_PRESENT +#error "RTC can only clock by LXT but LXT is not present. Try disabling RTC by \"device_has_remove\" in mbed_app.json" +#endif + /* Micro seconds per second */ #define NU_US_PER_SEC 1000000 /* Timer clock per second * * NOTE: This dependents on real hardware. */ +#if MBED_CONF_TARGET_LXT_PRESENT #define NU_RTCCLK_PER_SEC __LXT +#else +#define NU_RTCCLK_PER_SEC __LIRC +#endif /* Strategy for implementation of RTC HAL * @@ -86,7 +100,11 @@ static time_t t_write = 0; /* Convert date time from H/W RTC to struct TM */ static void rtc_convert_datetime_hwrtc_to_tm(struct tm *datetime_tm, const S_RTC_TIME_DATA_T *datetime_hwrtc); +#if MBED_CONF_TARGET_LXT_PRESENT static const struct nu_modinit_s rtc_modinit = {RTC_0, RTC_MODULE, CLK_CLKSEL3_RTCSEL_LXT, 0, 0, RTC_IRQn, NULL}; +#else +static const struct nu_modinit_s rtc_modinit = {RTC_0, RTC_MODULE, CLK_CLKSEL3_RTCSEL_LIRC, 0, 0, RTC_IRQn, NULL}; +#endif void rtc_init(void) { diff --git a/targets/TARGET_NUVOTON/TARGET_M480/watchdog_api.c b/targets/TARGET_NUVOTON/TARGET_M480/watchdog_api.c index 18e160da3e..4157e30940 100644 --- a/targets/TARGET_NUVOTON/TARGET_M480/watchdog_api.c +++ b/targets/TARGET_NUVOTON/TARGET_M480/watchdog_api.c @@ -22,26 +22,12 @@ #include "cmsis.h" -/* Define WDT clock source in target configuration option */ -#ifndef MBED_CONF_TARGET_WDT_CLKSRC_SEL -#define MBED_CONF_TARGET_WDT_CLKSRC_SEL LXT -#endif - -/* WDT clock source definition */ -#define NU_INTERN_WDT_CLKSRC_LXT 1 -#define NU_INTERN_WDT_CLKSRC_LIRC 2 - -/* WDT clock source selection */ -#define NU_INTERN_WDT_CLKSRC_SEL__(SEL) NU_INTERN_WDT_CLKSRC_##SEL -#define NU_INTERN_WDT_CLKSRC_SEL_(SEL) NU_INTERN_WDT_CLKSRC_SEL__(SEL) -#define NU_INTERN_WDT_CLKSRC_SEL NU_INTERN_WDT_CLKSRC_SEL_(MBED_CONF_TARGET_WDT_CLKSRC_SEL) - /* Watchdog clock per second */ -#if NU_INTERN_WDT_CLKSRC_SEL == NU_INTERN_WDT_CLKSRC_LXT +#if MBED_CONF_TARGET_LXT_PRESENT #define NU_WDTCLK_PER_SEC (__LXT) #define NU_WDTCLK_PER_SEC_MAX (__LXT) #define NU_WDTCLK_PER_SEC_MIN (__LXT) -#elif NU_INTERN_WDT_CLKSRC_SEL == NU_INTERN_WDT_CLKSRC_LIRC +#else #define NU_WDTCLK_PER_SEC (__LIRC) #define NU_WDTCLK_PER_SEC_MAX ((uint32_t) ((__LIRC) * 2.0f)) #define NU_WDTCLK_PER_SEC_MIN ((uint32_t) ((__LIRC) * 0.5f)) @@ -106,9 +92,9 @@ watchdog_status_t hal_watchdog_init(const watchdog_config_t *config) CLK_EnableModuleClock(WDT_MODULE); /* Select IP clock source */ -#if NU_INTERN_WDT_CLKSRC_SEL == NU_INTERN_WDT_CLKSRC_LXT +#if MBED_CONF_TARGET_LXT_PRESENT CLK_SetModuleClock(WDT_MODULE, CLK_CLKSEL1_WDTSEL_LXT, 0); -#elif NU_INTERN_WDT_CLKSRC_SEL == NU_INTERN_WDT_CLKSRC_LIRC +#else CLK_SetModuleClock(WDT_MODULE, CLK_CLKSEL1_WDTSEL_LIRC, 0); #endif diff --git a/targets/TARGET_NUVOTON/TARGET_NANO100/lp_ticker.c b/targets/TARGET_NUVOTON/TARGET_NANO100/lp_ticker.c index 9162337f5d..190e4358bb 100644 --- a/targets/TARGET_NUVOTON/TARGET_NANO100/lp_ticker.c +++ b/targets/TARGET_NUVOTON/TARGET_NANO100/lp_ticker.c @@ -29,7 +29,11 @@ /* Timer clock per lp_ticker tick */ #define NU_TMRCLK_PER_TICK 1 /* Timer clock per second */ +#if MBED_CONF_TARGET_LXT_PRESENT #define NU_TMRCLK_PER_SEC (__LXT) +#else +#define NU_TMRCLK_PER_SEC (__LIRC) +#endif /* Timer max counter bit size */ #define NU_TMR_MAXCNT_BITSIZE 24 /* Timer max counter */ @@ -40,7 +44,11 @@ void TMR1_IRQHandler(void); /* NOTE: To wake the system from power down mode, timer clock source must be ether LXT or LIRC. */ +#if MBED_CONF_TARGET_LXT_PRESENT static const struct nu_modinit_s timer1_modinit = {TIMER_1, TMR1_MODULE, CLK_CLKSEL1_TMR1_S_LXT, 0, TMR1_RST, TMR1_IRQn, (void *) TMR1_IRQHandler}; +#else +static const struct nu_modinit_s timer1_modinit = {TIMER_1, TMR1_MODULE, CLK_CLKSEL1_TMR1_S_LIRC, 0, TMR1_RST, TMR1_IRQn, (void *) TMR1_IRQHandler}; +#endif #define TIMER_MODINIT timer1_modinit diff --git a/targets/TARGET_NUVOTON/TARGET_NANO100/mbed_overrides.c b/targets/TARGET_NUVOTON/TARGET_NANO100/mbed_overrides.c index 9e2e10082e..8a6c946e0b 100644 --- a/targets/TARGET_NUVOTON/TARGET_NANO100/mbed_overrides.c +++ b/targets/TARGET_NUVOTON/TARGET_NANO100/mbed_overrides.c @@ -33,24 +33,36 @@ void mbed_sdk_init(void) /* Enable HIRC clock (internal OSC 12MHz) */ CLK_EnableXtalRC(CLK_PWRCTL_HIRC_EN_Msk); +#if MBED_CONF_TARGET_HXT_PRESENT /* Enable HXT clock (external XTAL 12MHz) */ CLK_EnableXtalRC(CLK_PWRCTL_HXT_EN_Msk); - /* Enable LIRC clock (OSC 10KHz) for lp_ticker */ +#endif + /* Enable LIRC clock (OSC 10KHz) */ CLK_EnableXtalRC(CLK_PWRCTL_LIRC_EN_Msk); - /* Enable LXT clock (XTAL 32KHz) for RTC */ +#if MBED_CONF_TARGET_LXT_PRESENT + /* Enable LXT clock (XTAL 32KHz) */ CLK_EnableXtalRC(CLK_PWRCTL_LXT_EN_Msk); +#endif /* Wait for HIRC clock ready */ CLK_WaitClockReady(CLK_CLKSTATUS_HIRC_STB_Msk); +#if MBED_CONF_TARGET_HXT_PRESENT /* Wait for HXT clock ready */ CLK_WaitClockReady(CLK_CLKSTATUS_HXT_STB_Msk); +#endif /* Wait for LIRC clock ready */ CLK_WaitClockReady(CLK_CLKSTATUS_LIRC_STB_Msk); +#if MBED_CONF_TARGET_LXT_PRESENT /* Wait for LXT clock ready */ CLK_WaitClockReady(CLK_CLKSTATUS_LXT_STB_Msk); +#endif - /* Set HCLK source form HXT and HCLK source divide 1 */ + /* Set HCLK source form HXT/HIRC and HCLK source divide 1 */ +#if MBED_CONF_TARGET_HXT_PRESENT CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_HXT, CLK_HCLK_CLK_DIVIDER(1)); +#else + CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_HIRC, CLK_HCLK_CLK_DIVIDER(1)); +#endif /* Select HXT/HIRC to clock PLL * @@ -75,6 +87,10 @@ void mbed_sdk_init(void) #define NU_CLOCK_PLL NU_HIRC_PLL #endif +#if (NU_CLOCK_PLL == NU_HXT_PLL) && (MBED_CONF_TARGET_HXT_PRESENT == 0) +#error "HXT is not present to clock PLL" +#endif + #if (NU_CLOCK_PLL == NU_HXT_PLL) CLK_EnablePLL(CLK_PLLCTL_PLL_SRC_HXT, FREQ_48MHZ*2); CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_PLL, CLK_HCLK_CLK_DIVIDER(2)); diff --git a/targets/TARGET_NUVOTON/TARGET_NANO100/rtc_api.c b/targets/TARGET_NUVOTON/TARGET_NANO100/rtc_api.c index 64d1cbacc2..2a117468f1 100644 --- a/targets/TARGET_NUVOTON/TARGET_NANO100/rtc_api.c +++ b/targets/TARGET_NUVOTON/TARGET_NANO100/rtc_api.c @@ -24,6 +24,14 @@ #include "nu_miscutil.h" #include "mbed_mktime.h" +/* Not support LIRC-clocked RTC + * + * H/W doesn't support this path. + */ +#if !MBED_CONF_TARGET_LXT_PRESENT +#error "RTC can only clock by LXT but LXT is not present. Try disabling RTC by \"device_has_remove\" in mbed_app.json" +#endif + /* Micro seconds per second */ #define NU_US_PER_SEC 1000000 /* Timer clock per second diff --git a/targets/TARGET_NUVOTON/TARGET_NANO100/us_ticker.c b/targets/TARGET_NUVOTON/TARGET_NANO100/us_ticker.c index 9298fd8d92..4a3f0e56c2 100644 --- a/targets/TARGET_NUVOTON/TARGET_NANO100/us_ticker.c +++ b/targets/TARGET_NUVOTON/TARGET_NANO100/us_ticker.c @@ -38,7 +38,11 @@ Vector table relocation is not actually supported for low-resource target. */ void TMR0_IRQHandler(void); +#if MBED_CONF_TARGET_HXT_PRESENT static const struct nu_modinit_s timer0_modinit = {TIMER_0, TMR0_MODULE, CLK_CLKSEL1_TMR0_S_HXT, 0, TMR0_RST, TMR0_IRQn, (void *) TMR0_IRQHandler}; +#else +static const struct nu_modinit_s timer0_modinit = {TIMER_0, TMR0_MODULE, CLK_CLKSEL1_TMR0_S_HIRC, 0, TMR0_RST, TMR0_IRQn, (void *) TMR0_IRQHandler}; +#endif #define TIMER_MODINIT timer0_modinit diff --git a/targets/TARGET_NUVOTON/TARGET_NANO100/watchdog_api.c b/targets/TARGET_NUVOTON/TARGET_NANO100/watchdog_api.c index 502f59bf3c..f5432386bd 100644 --- a/targets/TARGET_NUVOTON/TARGET_NANO100/watchdog_api.c +++ b/targets/TARGET_NUVOTON/TARGET_NANO100/watchdog_api.c @@ -20,31 +20,12 @@ #include "cmsis.h" -/* Define WDT clock source in target configuration option */ -#ifndef MBED_CONF_TARGET_WDT_CLKSRC_SEL -#define MBED_CONF_TARGET_WDT_CLKSRC_SEL LIRC -#endif - -/* WDT clock source definition */ -#define NU_INTERN_WDT_CLKSRC_LXT 1 -/* Not support LIRC clocked WDT */ -//#define NU_INTERN_WDT_CLKSRC_LIRC 2 - -/* WDT clock source selection */ -#define NU_INTERN_WDT_CLKSRC_SEL__(SEL) NU_INTERN_WDT_CLKSRC_##SEL -#define NU_INTERN_WDT_CLKSRC_SEL_(SEL) NU_INTERN_WDT_CLKSRC_SEL__(SEL) -#define NU_INTERN_WDT_CLKSRC_SEL NU_INTERN_WDT_CLKSRC_SEL_(MBED_CONF_TARGET_WDT_CLKSRC_SEL) +/* WDT can only clock by LIRC */ /* Watchdog clock per second */ -#if NU_INTERN_WDT_CLKSRC_SEL == NU_INTERN_WDT_CLKSRC_LXT -#define NU_WDTCLK_PER_SEC (__LXT) -#define NU_WDTCLK_PER_SEC_MAX (__LXT) -#define NU_WDTCLK_PER_SEC_MIN (__LXT) -#elif NU_INTERN_WDT_CLKSRC_SEL == NU_INTERN_WDT_CLKSRC_LIRC #define NU_WDTCLK_PER_SEC (__LIRC) #define NU_WDTCLK_PER_SEC_MAX ((uint32_t) ((__LIRC) * 1.5f)) #define NU_WDTCLK_PER_SEC_MIN ((uint32_t) ((__LIRC) * 0.5f)) -#endif /* Convert watchdog clock to nearest ms */ #define NU_WDTCLK2MS(WDTCLK) (((WDTCLK) * 1000 + ((NU_WDTCLK_PER_SEC) / 2)) / (NU_WDTCLK_PER_SEC)) diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/lp_ticker.c b/targets/TARGET_NUVOTON/TARGET_NUC472/lp_ticker.c index 04aacbb4a6..44e367d2c1 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/lp_ticker.c +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/lp_ticker.c @@ -29,7 +29,11 @@ /* Timer clock per lp_ticker tick */ #define NU_TMRCLK_PER_TICK 1 /* Timer clock per second */ +#if MBED_CONF_TARGET_LXT_PRESENT #define NU_TMRCLK_PER_SEC (__LXT) +#else +#define NU_TMRCLK_PER_SEC (__LIRC) +#endif /* Timer max counter bit size */ #define NU_TMR_MAXCNT_BITSIZE 24 /* Timer max counter */ @@ -38,7 +42,11 @@ static void tmr1_vec(void); /* NOTE: To wake the system from power down mode, timer clock source must be ether LXT or LIRC. */ +#if MBED_CONF_TARGET_LXT_PRESENT static const struct nu_modinit_s timer1_modinit = {TIMER_1, TMR1_MODULE, CLK_CLKSEL1_TMR1SEL_LXT, 0, TMR1_RST, TMR1_IRQn, (void *) tmr1_vec}; +#else +static const struct nu_modinit_s timer1_modinit = {TIMER_1, TMR1_MODULE, CLK_CLKSEL1_TMR1SEL_LIRC, 0, TMR1_RST, TMR1_IRQn, (void *) tmr1_vec}; +#endif #define TIMER_MODINIT timer1_modinit diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/mbed_overrides.c b/targets/TARGET_NUVOTON/TARGET_NUC472/mbed_overrides.c index 143d0e8a74..f2fe8303c3 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/mbed_overrides.c +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/mbed_overrides.c @@ -32,28 +32,45 @@ void mbed_sdk_init(void) /* Unlock protected registers */ SYS_UnlockReg(); +#if MBED_CONF_TARGET_HXT_PRESENT /* Enable External XTAL (4~24 MHz) */ CLK_EnableXtalRC(CLK_PWRCTL_HXTEN_Msk); - /* Enable LIRC for lp_ticker */ +#endif + /* Enable LIRC */ CLK_EnableXtalRC(CLK_PWRCTL_LIRCEN_Msk); - /* Enable LXT for RTC */ +#if MBED_CONF_TARGET_LXT_PRESENT + /* Enable LXT */ CLK_EnableXtalRC(CLK_PWRCTL_LXTEN_Msk); +#endif +#if MBED_CONF_TARGET_HXT_PRESENT /* Waiting for External XTAL (4~24 MHz) ready */ CLK_WaitClockReady(CLK_STATUS_HXTSTB_Msk); +#endif /* Waiting for LIRC ready */ CLK_WaitClockReady(CLK_STATUS_LIRCSTB_Msk); +#if MBED_CONF_TARGET_LXT_PRESENT /* Waiting for LXT ready */ CLK_WaitClockReady(CLK_STATUS_LXTSTB_Msk); +#endif +#if MBED_CONF_TARGET_HXT_PRESENT /* Switch HCLK clock source to HXT */ CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_HXT,CLK_CLKDIV0_HCLK(1)); +#else + /* Switch HCLK clock source to HIRC */ + CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_HIRC,CLK_CLKDIV0_HCLK(1)); +#endif /* Set PLL to power down mode and PLLSTB bit in CLKSTATUS register will be cleared by hardware.*/ CLK->PLLCTL|= CLK_PLLCTL_PD_Msk; /* Set PLL frequency */ +#if MBED_CONF_TARGET_HXT_PRESENT CLK->PLLCTL = CLK_PLLCTL_84MHz_HXT; +#else + CLK->PLLCTL = CLK_PLLCTL_50MHz_HIRC; +#endif /* Waiting for clock ready */ CLK_WaitClockReady(CLK_STATUS_PLLSTB_Msk); @@ -61,12 +78,6 @@ void mbed_sdk_init(void) /* Switch HCLK clock source to PLL */ CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_PLL,CLK_CLKDIV0_HCLK(1)); - /* Enable IP clock */ - //CLK_EnableModuleClock(UART0_MODULE); - - /* Select IP clock source */ - //CLK_SetModuleClock(UART0_MODULE,CLK_CLKSEL1_UARTSEL_HXT,CLK_CLKDIV0_UART(1)); - #if DEVICE_ANALOGIN /* Vref connect to AVDD */ SYS->VREFCTL = (SYS->VREFCTL & ~SYS_VREFCTL_VREFCTL_Msk) | SYS_VREFCTL_VREF_AVDD; diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/rtc_api.c b/targets/TARGET_NUVOTON/TARGET_NUC472/rtc_api.c index 85da1d37c9..6bcf87fba0 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/rtc_api.c +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/rtc_api.c @@ -24,6 +24,14 @@ #include "nu_miscutil.h" #include "mbed_mktime.h" +/* Not support LIRC-clocked RTC + * + * H/W doesn't support this path. + */ +#if !MBED_CONF_TARGET_LXT_PRESENT +#error "RTC can only clock by LXT but LXT is not present. Try disabling RTC by \"device_has_remove\" in mbed_app.json" +#endif + /* Micro seconds per second */ #define NU_US_PER_SEC 1000000 /* Timer clock per second diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/us_ticker.c b/targets/TARGET_NUVOTON/TARGET_NUC472/us_ticker.c index 45a6993d76..0b14763937 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/us_ticker.c +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/us_ticker.c @@ -78,7 +78,13 @@ void us_ticker_init(void) uint32_t clk_timer = TIMER_GetModuleClock(timer_base); uint32_t prescale_timer = clk_timer / NU_TMRCLK_PER_SEC - 1; MBED_ASSERT((prescale_timer != (uint32_t) -1) && prescale_timer <= 127); + /* HIRC-clocked PLL fails to output 1MHz-aligned frequency + * + * PLL, clocked by HIRC instead of HXT, doesn't output 1MHz-aligned frequency. + */ +#if MBED_CONF_TARGET_HXT_PRESENT MBED_ASSERT((clk_timer % NU_TMRCLK_PER_SEC) == 0); +#endif uint32_t cmp_timer = TMR_CMP_MAX; MBED_ASSERT(cmp_timer >= TMR_CMP_MIN && cmp_timer <= TMR_CMP_MAX); timer_base->CTL = TIMER_CONTINUOUS_MODE | prescale_timer | TIMER_CTL_CNTDATEN_Msk; diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/watchdog_api.c b/targets/TARGET_NUVOTON/TARGET_NUC472/watchdog_api.c index d760721363..21d67aa6c3 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/watchdog_api.c +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/watchdog_api.c @@ -20,26 +20,12 @@ #include "cmsis.h" -/* Define WDT clock source in target configuration option */ -#ifndef MBED_CONF_TARGET_WDT_CLKSRC_SEL -#define MBED_CONF_TARGET_WDT_CLKSRC_SEL LXT -#endif - -/* WDT clock source definition */ -#define NU_INTERN_WDT_CLKSRC_LXT 1 -#define NU_INTERN_WDT_CLKSRC_LIRC 2 - -/* WDT clock source selection */ -#define NU_INTERN_WDT_CLKSRC_SEL__(SEL) NU_INTERN_WDT_CLKSRC_##SEL -#define NU_INTERN_WDT_CLKSRC_SEL_(SEL) NU_INTERN_WDT_CLKSRC_SEL__(SEL) -#define NU_INTERN_WDT_CLKSRC_SEL NU_INTERN_WDT_CLKSRC_SEL_(MBED_CONF_TARGET_WDT_CLKSRC_SEL) - /* Watchdog clock per second */ -#if NU_INTERN_WDT_CLKSRC_SEL == NU_INTERN_WDT_CLKSRC_LXT +#if MBED_CONF_TARGET_LXT_PRESENT #define NU_WDTCLK_PER_SEC (__LXT) #define NU_WDTCLK_PER_SEC_MAX (__LXT) #define NU_WDTCLK_PER_SEC_MIN (__LXT) -#elif NU_INTERN_WDT_CLKSRC_SEL == NU_INTERN_WDT_CLKSRC_LIRC +#else #define NU_WDTCLK_PER_SEC (__LIRC) #define NU_WDTCLK_PER_SEC_MAX ((uint32_t) ((__LIRC) * 1.4f)) #define NU_WDTCLK_PER_SEC_MIN ((uint32_t) ((__LIRC) * 0.6f)) @@ -104,9 +90,9 @@ watchdog_status_t hal_watchdog_init(const watchdog_config_t *config) CLK_EnableModuleClock(WDT_MODULE); /* Select IP clock source */ -#if NU_INTERN_WDT_CLKSRC_SEL == NU_INTERN_WDT_CLKSRC_LXT +#if MBED_CONF_TARGET_LXT_PRESENT CLK_SetModuleClock(WDT_MODULE, CLK_CLKSEL1_WDTSEL_LXT, 0); -#elif NU_INTERN_WDT_CLKSRC_SEL == NU_INTERN_WDT_CLKSRC_LIRC +#else CLK_SetModuleClock(WDT_MODULE, CLK_CLKSEL1_WDTSEL_LIRC, 0); #endif diff --git a/targets/targets.json b/targets/targets.json index a5f2e8fb2c..cf4a670964 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -6186,6 +6186,16 @@ "GCC_ARM" ], "config": { + "hxt-present": { + "help": "High-speed external crystal oscillator HXT is present", + "options": [false, true], + "value": false + }, + "lxt-present": { + "help": "Low-speed external crystal oscillator LXT is present", + "options": [false, true], + "value": true + }, "gpio-irq-debounce-enable": { "help": "Enable GPIO IRQ debounce", "value": 0 @@ -6250,6 +6260,8 @@ "device_name": "NUC472HI8AE", "bootloader_supported": true, "overrides": { + "hxt-present": true, + "lxt-present": true, "network-default-interface-type": "ETHERNET", "deep-sleep-latency": 1, "tickless-from-us-ticker": true @@ -6288,6 +6300,16 @@ "IAR" ], "config": { + "hxt-present": { + "help": "High-speed external crystal oscillator HXT is present", + "options": [false, true], + "value": false + }, + "lxt-present": { + "help": "Low-speed external crystal oscillator LXT is present", + "options": [false, true], + "value": true + }, "gpio-irq-debounce-enable": { "help": "Enable GPIO IRQ debounce", "value": 0 @@ -6375,6 +6397,8 @@ "device_name": "M453VG6AE", "bootloader_supported": true, "overrides": { + "hxt-present": true, + "lxt-present": true, "deep-sleep-latency": 1, "tickless-from-us-ticker": true }, @@ -6397,6 +6421,16 @@ "IAR" ], "config": { + "hxt-present": { + "help": "High-speed external crystal oscillator HXT is present", + "options": [false, true], + "value": false + }, + "lxt-present": { + "help": "Low-speed external crystal oscillator LXT is present", + "options": [false, true], + "value": true + }, "gpio-irq-debounce-enable": { "help": "Enable GPIO IRQ debounce", "value": 0 @@ -6476,6 +6510,8 @@ ], "device_name": "NANO130KE3BN", "overrides": { + "hxt-present": true, + "lxt-present": true, "deep-sleep-latency": 1, "tickless-from-us-ticker": true }, @@ -6499,6 +6535,16 @@ "GCC_ARM" ], "config": { + "hxt-present": { + "help": "High-speed external crystal oscillator HXT is present", + "options": [false, true], + "value": false + }, + "lxt-present": { + "help": "Low-speed external crystal oscillator LXT is present", + "options": [false, true], + "value": true + }, "spim-ccm-enable": { "help": "Enable SPIM CCM mode to spare 32KiB SRAM for normal use", "value": 0 @@ -6627,6 +6673,8 @@ "1304" ], "overrides": { + "hxt-present": true, + "lxt-present": true, "usb-uart": "UART_0", "usb-uart-tx": "PB_13", "usb-uart-rx": "PB_12", @@ -6646,6 +6694,8 @@ "1308" ], "overrides": { + "hxt-present": true, + "lxt-present": true, "usb-uart": "UART_0", "usb-uart-tx": "PB_13", "usb-uart-rx": "PB_12", @@ -6992,6 +7042,16 @@ "GCC_ARM" ], "config": { + "hxt-present": { + "help": "High-speed external crystal oscillator HXT is present", + "options": [false, true], + "value": false + }, + "lxt-present": { + "help": "Low-speed external crystal oscillator LXT is present", + "options": [false, true], + "value": true + }, "usb-uart": { "help": "Configure USB_UART. USB_UART and USB_UART_TX/USB_UART_RX must be consistent.", "value": null @@ -7039,6 +7099,8 @@ } }, "overrides": { + "hxt-present": false, + "lxt-present": true, "mpu-rom-end": "0x1fffffff", "deep-sleep-latency": 1, "tickless-from-us-ticker": true @@ -7927,6 +7989,16 @@ "GCC_ARM" ], "config": { + "hxt-present": { + "help": "High-speed external crystal oscillator HXT is present", + "options": [false, true], + "value": false + }, + "lxt-present": { + "help": "Low-speed external crystal oscillator LXT is present", + "options": [false, true], + "value": true + }, "usb-uart": { "help": "Configure USB_UART. USB_UART and USB_UART_TX/USB_UART_RX must be consistent.", "value": null @@ -8012,6 +8084,8 @@ ], "bootloader_supported": true, "overrides": { + "hxt-present": true, + "lxt-present": true, "deep-sleep-latency": 1, "tickless-from-us-ticker": true },