[Nuvoton] Add missing delay in lp_ticker

mbed-os-tests-mbed_drivers-lp_ticker/Test multi ticker test fails inconstantly.
This commit is mainly to fix the issue.
pull/6394/head
ccli8 2018-03-26 09:45:59 +08:00
parent 5d453ed381
commit ccec9d75d6
4 changed files with 45 additions and 0 deletions
targets/TARGET_NUVOTON
TARGET_M451
TARGET_M480
TARGET_NANO100
TARGET_NUC472

View File

@ -47,6 +47,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) {
@ -75,8 +78,10 @@ void lp_ticker_init(void)
// Continuous mode
// NOTE: TIMER_CTL_CNTDATEN_Msk exists in NUC472, but not in M451. In M451, 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);
@ -84,11 +89,13 @@ 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);
wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3);
TIMER_Start(timer_base);
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));
@ -129,11 +136,13 @@ void lp_ticker_set_interrupt(timestamp_t timestamp)
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)
@ -155,8 +164,10 @@ const ticker_info_t* lp_ticker_get_info()
static void tmr1_vec(void)
{
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();

View File

@ -47,6 +47,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) {
@ -75,8 +78,10 @@ void lp_ticker_init(void)
// Continuous mode
// NOTE: TIMER_CTL_CNTDATEN_Msk exists in NUC472, but not in M451/M480. In M451/M480, 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);
@ -84,11 +89,13 @@ 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);
wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3);
TIMER_Start(timer_base);
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));
@ -129,11 +136,13 @@ void lp_ticker_set_interrupt(timestamp_t timestamp)
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)
@ -155,8 +164,10 @@ const ticker_info_t* lp_ticker_get_info()
static void tmr1_vec(void)
{
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();

View File

@ -49,6 +49,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) {
@ -76,10 +79,13 @@ void lp_ticker_init(void)
MBED_ASSERT(cmp_timer >= TMR_CMP_MIN && cmp_timer <= TMR_CMP_MAX);
// Continuous mode
timer_base->CTL = TIMER_CONTINUOUS_MODE;
wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3);
timer_base->PRECNT = prescale_timer;
wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3);
timer_base->CMPR = 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);
@ -87,11 +93,13 @@ 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);
wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3);
TIMER_Start(timer_base);
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_TMR_ACT_Msk));
@ -132,11 +140,13 @@ void lp_ticker_set_interrupt(timestamp_t timestamp)
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)
@ -158,8 +168,10 @@ const ticker_info_t* lp_ticker_get_info()
void TMR1_IRQHandler(void)
{
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();

View File

@ -47,6 +47,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) {
@ -74,8 +77,10 @@ void lp_ticker_init(void)
MBED_ASSERT(cmp_timer >= TMR_CMP_MIN && cmp_timer <= TMR_CMP_MAX);
// Continuous mode
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);
@ -83,11 +88,13 @@ 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);
wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3);
TIMER_Start(timer_base);
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));
@ -128,11 +135,13 @@ void lp_ticker_set_interrupt(timestamp_t timestamp)
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)
@ -154,8 +163,10 @@ const ticker_info_t* lp_ticker_get_info()
static void tmr1_vec(void)
{
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();