void lp_ticker_sleep_until(uint32_t now, uint32_t time) { lp_ticker_set_interrupt(now, time); sleep_t sleep_obj; mbed_enter_sleep(&sleep_obj); mbed_exit_sleep(&sleep_obj); }
void lp_ticker_init(void) { if (lp_ticker_inited) { return; } lp_ticker_inited = 1; counter_major = 0; cd_major_minor_clks = 0; cd_minor_clks = 0; wakeup_tick = (uint32_t) -1; // Reset module SYS_ResetModule(timer2_modinit.rsetidx); SYS_ResetModule(timer3_modinit.rsetidx); // Select IP clock source CLK_SetModuleClock(timer2_modinit.clkidx, timer2_modinit.clksrc, timer2_modinit.clkdiv); CLK_SetModuleClock(timer3_modinit.clkidx, timer3_modinit.clksrc, timer3_modinit.clkdiv); // Enable IP clock CLK_EnableModuleClock(timer2_modinit.clkidx); CLK_EnableModuleClock(timer3_modinit.clkidx); // Configure clock uint32_t clk_timer2 = TIMER_GetModuleClock((TIMER_T *) NU_MODBASE(timer2_modinit.modname)); uint32_t prescale_timer2 = clk_timer2 / TMR2_CLK_PER_SEC - 1; MBED_ASSERT((prescale_timer2 != (uint32_t) -1) && prescale_timer2 <= 127); MBED_ASSERT((clk_timer2 % TMR2_CLK_PER_SEC) == 0); uint32_t cmp_timer2 = TMR2_CLK_PER_TMR2_INT; MBED_ASSERT(cmp_timer2 >= TMR_CMP_MIN && cmp_timer2 <= TMR_CMP_MAX); // 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_T *) NU_MODBASE(timer2_modinit.modname))->CTL = TIMER_PERIODIC_MODE | prescale_timer2/* | TIMER_CTL_CNTDATEN_Msk*/; ((TIMER_T *) NU_MODBASE(timer2_modinit.modname))->CMP = cmp_timer2; // Set vector NVIC_SetVector(timer2_modinit.irq_n, (uint32_t) timer2_modinit.var); NVIC_SetVector(timer3_modinit.irq_n, (uint32_t) timer3_modinit.var); NVIC_EnableIRQ(timer2_modinit.irq_n); NVIC_EnableIRQ(timer3_modinit.irq_n); TIMER_EnableInt((TIMER_T *) NU_MODBASE(timer2_modinit.modname)); TIMER_EnableWakeup((TIMER_T *) NU_MODBASE(timer2_modinit.modname)); // NOTE: TIMER_Start() first and then lp_ticker_set_interrupt(); otherwise, we may get stuck in lp_ticker_read() because // timer is not running. // Start timer TIMER_Start((TIMER_T *) NU_MODBASE(timer2_modinit.modname)); // Schedule wakeup to match semantics of lp_ticker_get_compare_match() lp_ticker_set_interrupt(wakeup_tick); }
void lp_ticker_sleep_until(uint32_t now, uint32_t time) { lp_ticker_set_interrupt(now, time); sleep_t sleep_obj; mbed_enter_sleep(&sleep_obj); // if LPTMR is running and we scheduled it, we know that RTC was fired while // we were sleeping if (LPTMR_HAL_IsEnabled(LPTMR0_BASE) && lp_ticker_lptmr_scheduled_flag) { __WFI(); } mbed_exit_sleep(&sleep_obj); }
void lp_ticker_init(void) { if (lp_ticker_inited) { return; } lp_ticker_inited = 1; counter_major = 0; cd_major_minor_ms = 0; cd_minor_ms = 0; wakeup_tick = TMR_CMP_MAX * MS_PER_TMR2_CLK / MS_PER_TICK; // Reset module SYS_ResetModule(timer2_modinit.rsetidx); SYS_ResetModule(timer3_modinit.rsetidx); // Select IP clock source CLK_SetModuleClock(timer2_modinit.clkidx, timer2_modinit.clksrc, timer2_modinit.clkdiv); CLK_SetModuleClock(timer3_modinit.clkidx, timer3_modinit.clksrc, timer3_modinit.clkdiv); // Enable IP clock CLK_EnableModuleClock(timer2_modinit.clkidx); CLK_EnableModuleClock(timer3_modinit.clkidx); // Configure clock uint32_t clk_timer2 = TIMER_GetModuleClock((TIMER_T *) NU_MODBASE(timer2_modinit.modname)); uint32_t prescale_timer2 = clk_timer2 / TMR2_CLK_FREQ - 1; MBED_ASSERT((prescale_timer2 != (uint32_t) -1) && prescale_timer2 <= 127); uint32_t cmp_timer2 = MS_PER_TMR2_INT / MS_PER_TMR2_CLK; MBED_ASSERT(cmp_timer2 >= TMR_CMP_MIN && cmp_timer2 <= TMR_CMP_MAX); // Continuous mode ((TIMER_T *) NU_MODBASE(timer2_modinit.modname))->CTL = TIMER_PERIODIC_MODE | prescale_timer2 | TIMER_CTL_CNTDATEN_Msk; ((TIMER_T *) NU_MODBASE(timer2_modinit.modname))->CMP = cmp_timer2; // Set vector NVIC_SetVector(timer2_modinit.irq_n, (uint32_t) timer2_modinit.var); NVIC_SetVector(timer3_modinit.irq_n, (uint32_t) timer3_modinit.var); NVIC_EnableIRQ(timer2_modinit.irq_n); NVIC_EnableIRQ(timer3_modinit.irq_n); TIMER_EnableInt((TIMER_T *) NU_MODBASE(timer2_modinit.modname)); TIMER_EnableWakeup((TIMER_T *) NU_MODBASE(timer2_modinit.modname)); // Schedule wakeup to match semantics of lp_ticker_get_compare_match() lp_ticker_set_interrupt(lp_ticker_read(), wakeup_tick); // Start timer TIMER_Start((TIMER_T *) NU_MODBASE(timer2_modinit.modname)); }