From fa0124ed8d7dc672b7c02dbc25c7e6881ff15b36 Mon Sep 17 00:00:00 2001 From: ccli8 Date: Fri, 16 Mar 2018 15:12:10 +0800 Subject: [PATCH] [M2351] Add missing delay in lp_ticker --- .../TARGET_NUVOTON/TARGET_M2351/lp_ticker.c | 30 ++++++++++++------- .../TARGET_NUVOTON/TARGET_M2351/us_ticker.c | 1 + 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/targets/TARGET_NUVOTON/TARGET_M2351/lp_ticker.c b/targets/TARGET_NUVOTON/TARGET_M2351/lp_ticker.c index 6cd58dc166..ce2c3a4e06 100644 --- a/targets/TARGET_NUVOTON/TARGET_M2351/lp_ticker.c +++ b/targets/TARGET_NUVOTON/TARGET_M2351/lp_ticker.c @@ -72,6 +72,9 @@ static int ticker_inited = 0; #define TMR_CMP_MIN 2 #define TMR_CMP_MAX 0xFFFFFFu +/* NOTE: When system clock is higher than timer clock, we need to add 3 engine clock + * (recommended by designer) delay to wait for above timer control to take effect. */ + void lp_ticker_init(void) { if (ticker_inited) { @@ -109,7 +112,10 @@ void lp_ticker_init(void) // Continuous mode // NOTE: TIMER_CTL_CNTDATEN_Msk exists in NUC472, but not in M451/M480/M2351. In M451/M480/M2351, TIMER_CNT is updated continuously by default. timer_base->CTL = TIMER_CONTINUOUS_MODE | prescale_timer/* | TIMER_CTL_CNTDATEN_Msk*/; + wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3); + timer_base->CMP = cmp_timer; + wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3); // Set vector NVIC_SetVector(TIMER_MODINIT.irq_n, (uint32_t) TIMER_MODINIT.var); @@ -117,20 +123,15 @@ void lp_ticker_init(void) NVIC_EnableIRQ(TIMER_MODINIT.irq_n); TIMER_EnableInt(timer_base); + wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3); + TIMER_EnableWakeup(timer_base); - - /* NOTE: When system clock is higher than timer clock, we need to add 3 engine clock - * (recommended by designer) delay to wait for above timer control to take effect. */ - - /* Add delay to wait for above timer control to take effect before enabling timer counting */ wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3); + TIMER_Start(timer_base); - - /* Add delay to wait for timer to start counting and raise active flag - * - * It is possible timer active bit cannot be set in time while we check it, and the while loop - * below would return immediately. */ wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3); + + /* Wait for timer to start counting and raise active flag */ while(! (timer_base->CTL & TIMER_CTL_ACTSTS_Msk)); } @@ -161,17 +162,21 @@ void lp_ticker_set_interrupt(timestamp_t timestamp) * (TMR_CMP_MIN - interval_clk) clocks when interval_clk is between [1, TMR_CMP_MIN). */ uint32_t cmp_timer = timestamp * NU_TMRCLK_PER_TICK; cmp_timer = NU_CLAMP(cmp_timer, TMR_CMP_MIN, TMR_CMP_MAX); + timer_base->CMP = cmp_timer; + wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3); } void lp_ticker_disable_interrupt(void) { TIMER_DisableInt((TIMER_T *) NU_MODBASE(TIMER_MODINIT.modname)); + wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3); } void lp_ticker_clear_interrupt(void) { TIMER_ClearIntFlag((TIMER_T *) NU_MODBASE(TIMER_MODINIT.modname)); + wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3); } void lp_ticker_fire_interrupt(void) @@ -197,8 +202,11 @@ static void tmr3_vec(void) #endif { TIMER_ClearIntFlag((TIMER_T *) NU_MODBASE(TIMER_MODINIT.modname)); + wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3); + TIMER_ClearWakeupFlag((TIMER_T *) NU_MODBASE(TIMER_MODINIT.modname)); - + wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3); + // NOTE: lp_ticker_set_interrupt() may get called in lp_ticker_irq_handler(); lp_ticker_irq_handler(); } diff --git a/targets/TARGET_NUVOTON/TARGET_M2351/us_ticker.c b/targets/TARGET_NUVOTON/TARGET_M2351/us_ticker.c index 573d1a6d25..5316777f90 100644 --- a/targets/TARGET_NUVOTON/TARGET_M2351/us_ticker.c +++ b/targets/TARGET_NUVOTON/TARGET_M2351/us_ticker.c @@ -111,6 +111,7 @@ void us_ticker_init(void) TIMER_EnableInt(timer_base); TIMER_Start(timer_base); + /* Wait for timer to start counting and raise active flag */ while(! (timer_base->CTL & TIMER_CTL_ACTSTS_Msk)); }