From 0803267eabd4c202b6f4e482febba47c3df3bf2a Mon Sep 17 00:00:00 2001 From: ccli8 Date: Thu, 20 Jul 2017 10:14:57 +0800 Subject: [PATCH] [M487] Add ticker API us_ticker_fire_interrupt and lp_ticker_fire_interrupt --- .../TARGET_NUVOTON/TARGET_M480/lp_ticker.c | 25 +++++++++---------- .../TARGET_NUVOTON/TARGET_M480/us_ticker.c | 18 ++++++++----- 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/targets/TARGET_NUVOTON/TARGET_M480/lp_ticker.c b/targets/TARGET_NUVOTON/TARGET_M480/lp_ticker.c index 36bf2dc46b..6e07e785fa 100644 --- a/targets/TARGET_NUVOTON/TARGET_M480/lp_ticker.c +++ b/targets/TARGET_NUVOTON/TARGET_M480/lp_ticker.c @@ -149,27 +149,26 @@ void lp_ticker_set_interrupt(timestamp_t timestamp) TIMER_Stop((TIMER_T *) NU_MODBASE(timer3_modinit.modname)); - /** - * FIXME: Scheduled alarm may go off incorrectly due to wrap around. - * Conditions in which delta is negative: - * 1. Wrap around - * 2. Newly scheduled alarm is behind now - */ - //int delta = (timestamp > now) ? (timestamp - now) : (uint32_t) ((uint64_t) timestamp + 0xFFFFFFFFu - now); int delta = (int) (timestamp - now); if (delta > 0) { cd_major_minor_clks = (uint64_t) delta * US_PER_TICK * TMR3_CLK_PER_SEC / US_PER_SEC; lp_ticker_arm_cd(); } else { - cd_major_minor_clks = cd_minor_clks = 0; - /** - * This event was in the past. Set the interrupt as pending, but don't process it here. - * This prevents a recurive loop under heavy load which can lead to a stack overflow. - */ - NVIC_SetPendingIRQ(timer3_modinit.irq_n); + // NOTE: With lp_ticker_fire_interrupt() introduced, upper layer would handle past event case. + // This code fragment gets redundant, but it is still kept here for backward-compatible. + void lp_ticker_fire_interrupt(void); + lp_ticker_fire_interrupt(); } } +void lp_ticker_fire_interrupt(void) +{ + // NOTE: This event was in the past. Set the interrupt as pending, but don't process it here. + // This prevents a recursive loop under heavy load which can lead to a stack overflow. + cd_major_minor_clks = cd_minor_clks = 0; + NVIC_SetPendingIRQ(timer3_modinit.irq_n); +} + void lp_ticker_disable_interrupt(void) { TIMER_DisableInt((TIMER_T *) NU_MODBASE(timer3_modinit.modname)); diff --git a/targets/TARGET_NUVOTON/TARGET_M480/us_ticker.c b/targets/TARGET_NUVOTON/TARGET_M480/us_ticker.c index cfcad67cc3..6665c3cfa4 100644 --- a/targets/TARGET_NUVOTON/TARGET_M480/us_ticker.c +++ b/targets/TARGET_NUVOTON/TARGET_M480/us_ticker.c @@ -152,15 +152,21 @@ void us_ticker_set_interrupt(timestamp_t timestamp) cd_major_minor_us = delta * US_PER_TICK; us_ticker_arm_cd(); } else { - cd_major_minor_us = cd_minor_us = 0; - /** - * This event was in the past. Set the interrupt as pending, but don't process it here. - * This prevents a recurive loop under heavy load which can lead to a stack overflow. - */ - NVIC_SetPendingIRQ(timer1hires_modinit.irq_n); + // NOTE: With us_ticker_fire_interrupt() introduced, upper layer would handle past event case. + // This code fragment gets redundant, but it is still kept here for backward-compatible. + void us_ticker_fire_interrupt(void); + us_ticker_fire_interrupt(); } } +void us_ticker_fire_interrupt(void) +{ + // NOTE: This event was in the past. Set the interrupt as pending, but don't process it here. + // This prevents a recursive loop under heavy load which can lead to a stack overflow. + cd_major_minor_us = cd_minor_us = 0; + NVIC_SetPendingIRQ(timer1hires_modinit.irq_n); +} + static void tmr0_vec(void) { TIMER_ClearIntFlag((TIMER_T *) NU_MODBASE(timer0hires_modinit.modname));