void lp_ticker_set_interrupt(timestamp_t timestamp) { uint32_t now = lp_ticker_read(); wakeup_tick = 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); } }
static void tmr3_vec(void) { TIMER_ClearIntFlag((TIMER_T *) NU_MODBASE(timer3_modinit.modname)); TIMER_ClearWakeupFlag((TIMER_T *) NU_MODBASE(timer3_modinit.modname)); cd_major_minor_ms -= cd_minor_ms; if (cd_major_minor_ms > 0) { lp_ticker_arm_cd(); } }
void lp_ticker_set_interrupt(timestamp_t timestamp) { uint32_t delta = timestamp - lp_ticker_read(); wakeup_tick = timestamp; TIMER_Stop((TIMER_T *) NU_MODBASE(timer3_modinit.modname)); cd_major_minor_clks = (uint64_t) delta * US_PER_TICK * TMR3_CLK_PER_SEC / US_PER_SEC; lp_ticker_arm_cd(); }
void lp_ticker_set_interrupt(uint32_t now, uint32_t time) { wakeup_tick = time; TIMER_Stop((TIMER_T *) NU_MODBASE(timer3_modinit.modname)); int delta = (time > now) ? (time - now) : (uint32_t) ((uint64_t) time + 0xFFFFFFFFu - now); // NOTE: If this event was in the past, arm an interrupt to be triggered immediately. cd_major_minor_ms = delta * MS_PER_TICK; lp_ticker_arm_cd(); }
static void tmr3_vec(void) { TIMER_ClearIntFlag((TIMER_T *) NU_MODBASE(timer3_modinit.modname)); TIMER_ClearWakeupFlag((TIMER_T *) NU_MODBASE(timer3_modinit.modname)); cd_major_minor_clks = (cd_major_minor_clks > cd_minor_clks) ? (cd_major_minor_clks - cd_minor_clks) : 0; if (cd_major_minor_clks == 0) { // NOTE: lp_ticker_set_interrupt() may get called in lp_ticker_irq_handler(); lp_ticker_irq_handler(); } else { lp_ticker_arm_cd(); } }