static void lp_ticker_arm_cd(void) { TIMER_T * timer3_base = (TIMER_T *) NU_MODBASE(timer3_modinit.modname); // Reset 8-bit PSC counter, 24-bit up counter value and CNTEN bit // NUC472/M451: See TIMER_CTL_RSTCNT_Msk // M480 timer3_base->CNT = 0; while (timer3_base->CNT & TIMER_CNT_RSTACT_Msk); // One-shot mode, Clock = 1 KHz uint32_t clk_timer3 = TIMER_GetModuleClock((TIMER_T *) NU_MODBASE(timer3_modinit.modname)); uint32_t prescale_timer3 = clk_timer3 / TMR3_CLK_PER_SEC - 1; MBED_ASSERT((prescale_timer3 != (uint32_t) -1) && prescale_timer3 <= 127); MBED_ASSERT((clk_timer3 % TMR3_CLK_PER_SEC) == 0); // NOTE: TIMER_CTL_CNTDATEN_Msk exists in NUC472, but not in M451/M480. In M451/M480, TIMER_CNT is updated continuously by default. timer3_base->CTL &= ~(TIMER_CTL_OPMODE_Msk | TIMER_CTL_PSC_Msk/* | TIMER_CTL_CNTDATEN_Msk*/); timer3_base->CTL |= TIMER_ONESHOT_MODE | prescale_timer3/* | TIMER_CTL_CNTDATEN_Msk*/; cd_minor_clks = cd_major_minor_clks; cd_minor_clks = NU_CLAMP(cd_minor_clks, TMR_CMP_MIN, TMR_CMP_MAX); timer3_base->CMP = cd_minor_clks; TIMER_EnableInt(timer3_base); TIMER_EnableWakeup((TIMER_T *) NU_MODBASE(timer3_modinit.modname)); TIMER_Start(timer3_base); }
void us_ticker_init(void) { if (ticker_inited) { return; } ticker_inited = 1; // Reset IP SYS_ResetModule(TIMER_MODINIT.rsetidx); // Select IP clock source CLK_SetModuleClock(TIMER_MODINIT.clkidx, TIMER_MODINIT.clksrc, TIMER_MODINIT.clkdiv); // Enable IP clock CLK_EnableModuleClock(TIMER_MODINIT.clkidx); // Timer for normal counter uint32_t clk_timer = TIMER_GetModuleClock((TIMER_T *) NU_MODBASE(TIMER_MODINIT.modname)); uint32_t prescale_timer = clk_timer / NU_TMRCLK_PER_SEC - 1; MBED_ASSERT((prescale_timer != (uint32_t) -1) && prescale_timer <= 127); MBED_ASSERT((clk_timer % NU_TMRCLK_PER_SEC) == 0); uint32_t cmp_timer = TMR_CMP_MAX; MBED_ASSERT(cmp_timer >= TMR_CMP_MIN && cmp_timer <= TMR_CMP_MAX); // NOTE: TIMER_CTL_CNTDATEN_Msk exists in NUC472, but not in M451. In M451, TIMER_CNT is updated continuously by default. ((TIMER_T *) NU_MODBASE(TIMER_MODINIT.modname))->CTL = TIMER_CONTINUOUS_MODE | prescale_timer/* | TIMER_CTL_CNTDATEN_Msk*/; ((TIMER_T *) NU_MODBASE(TIMER_MODINIT.modname))->CMP = cmp_timer; NVIC_SetVector(TIMER_MODINIT.irq_n, (uint32_t) TIMER_MODINIT.var); NVIC_EnableIRQ(TIMER_MODINIT.irq_n); TIMER_EnableInt((TIMER_T *) NU_MODBASE(TIMER_MODINIT.modname)); TIMER_Start((TIMER_T *) NU_MODBASE(TIMER_MODINIT.modname)); }
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); }
/** * @brief This API is used to configure timer to operate in specified mode * and frequency. If timer cannot work in target frequency, a closest * frequency will be chose and returned. * @param[in] timer The base address of Timer module * @param[in] u32Mode Operation mode. Possible options are * - \ref TIMER_ONESHOT_MODE * - \ref TIMER_PERIODIC_MODE * - \ref TIMER_TOGGLE_MODE * - \ref TIMER_CONTINUOUS_MODE * @param[in] u32Freq Target working frequency * @return Real Timer working frequency * @note After calling this API, Timer is \b NOT running yet. But could start timer running be calling * \ref TIMER_Start macro or program registers directly */ uint32_t TIMER_Open(TIMER_T *timer, uint32_t u32Mode, uint32_t u32Freq) { uint32_t u32Clk = TIMER_GetModuleClock(timer); uint32_t u32Cmpr = 0, u32Prescale = 0; // Fastest possible timer working freq is u32Clk / 2. While cmpr = 2, pre-scale = 0 if(u32Freq > (u32Clk / 2)) { u32Cmpr = 2; } else { if(u32Clk >= 0x2000000) { u32Prescale = 3; // real prescaler value is 4 u32Clk >>= 2; } else if(u32Clk >= 0x1000000) {
/** * @brief Open Timer with Operate Mode and Frequency * * @param[in] timer The pointer of the specified Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3. * @param[in] u32Mode Operation mode. Possible options are * - \ref TIMER_ONESHOT_MODE * - \ref TIMER_PERIODIC_MODE * - \ref TIMER_TOGGLE_MODE * - \ref TIMER_CONTINUOUS_MODE * @param[in] u32Freq Target working frequency * * @return Real timer working frequency * * @details This API is used to configure timer to operate in specified mode and frequency. * If timer cannot work in target frequency, a closest frequency will be chose and returned. * @note After calling this API, Timer is \b NOT running yet. But could start timer running be calling * \ref TIMER_Start macro or program registers directly. */ uint32_t TIMER_Open(TIMER_T *timer, uint32_t u32Mode, uint32_t u32Freq) { uint32_t u32Clk = TIMER_GetModuleClock(timer); uint32_t u32Cmpr = 0UL, u32Prescale = 0UL; /* Fastest possible timer working freq is (u32Clk / 2). While cmpr = 2, prescaler = 0. */ if(u32Freq > (u32Clk / 2UL)) { u32Cmpr = 2UL; } else { if(u32Clk > 128000000UL) { u32Prescale = 15UL; /* real prescaler value is 16 */ u32Clk >>= 4; } else if(u32Clk > 64000000UL) {
void us_ticker_init(void) { if (ticker_inited) { /* By HAL spec, ticker_init allows the ticker to keep counting and disables the * ticker interrupt. */ us_ticker_disable_interrupt(); return; } ticker_inited = 1; /* Reset module * * NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure. */ SYS_ResetModule_S(TIMER_MODINIT.rsetidx); /* Select IP clock source * * NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure. */ CLK_SetModuleClock_S(TIMER_MODINIT.clkidx, TIMER_MODINIT.clksrc, TIMER_MODINIT.clkdiv); /* Enable IP clock * * NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure. */ CLK_EnableModuleClock_S(TIMER_MODINIT.clkidx); TIMER_T *timer_base = (TIMER_T *) NU_MODBASE(TIMER_MODINIT.modname); // Timer for normal counter uint32_t clk_timer = TIMER_GetModuleClock(timer_base); uint32_t prescale_timer = clk_timer / NU_TMRCLK_PER_SEC - 1; MBED_ASSERT((prescale_timer != (uint32_t) -1) && prescale_timer <= 127); MBED_ASSERT((clk_timer % NU_TMRCLK_PER_SEC) == 0); uint32_t cmp_timer = TMR_CMP_MAX; MBED_ASSERT(cmp_timer >= TMR_CMP_MIN && cmp_timer <= TMR_CMP_MAX); // 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*/; timer_base->CMP = cmp_timer; NVIC_SetVector(TIMER_MODINIT.irq_n, (uint32_t) TIMER_MODINIT.var); NVIC_DisableIRQ(TIMER_MODINIT.irq_n); 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)); }
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)); }
/** * @brief This API is used to configure timer to operate in specified mode * and frequency. If timer cannot work in target frequency, a closest * frequency will be chose and returned. * @param[in] timer The base address of Timer module * @param[in] u32Mode Operation mode. Possible options are * - \ref TIMER_ONESHOT_MODE * - \ref TIMER_PERIODIC_MODE * - \ref TIMER_TOGGLE_MODE * - \ref TIMER_CONTINUOUS_MODE * @param[in] u32Freq Target working frequency * @return Real Timer working frequency * @note After calling this API, Timer is \b NOT running yet. But could start timer running be calling * \ref TIMER_Start macro or program registers directly */ uint32_t TIMER_Open(TIMER_T *timer, uint32_t u32Mode, uint32_t u32Freq) { uint32_t u32Clk = TIMER_GetModuleClock(timer); uint32_t u32Cmpr = 0, u32Prescale = 0; // Fastest possible timer working freq is u32Clk / 2. While cmpr = 2, pre-scale = 0 if(u32Freq > (u32Clk / 2)) { u32Cmpr = 2; } else { if(u32Clk > 0xFFFFFF) { // For Mini, only needs to consider 24MHz at most u32Prescale = 1; u32Clk >>= 1; } u32Cmpr = u32Clk / u32Freq; }
void us_ticker_init(void) { if (us_ticker_inited) { return; } counter_major = 0; cd_major_minor_us = 0; cd_minor_us = 0; us_ticker_inited = 1; // Reset IP SYS_ResetModule(timer0hires_modinit.rsetidx); SYS_ResetModule(timer1hires_modinit.rsetidx); // Select IP clock source CLK_SetModuleClock(timer0hires_modinit.clkidx, timer0hires_modinit.clksrc, timer0hires_modinit.clkdiv); CLK_SetModuleClock(timer1hires_modinit.clkidx, timer1hires_modinit.clksrc, timer1hires_modinit.clkdiv); // Enable IP clock CLK_EnableModuleClock(timer0hires_modinit.clkidx); CLK_EnableModuleClock(timer1hires_modinit.clkidx); // Timer for normal counter uint32_t clk_timer0 = TIMER_GetModuleClock((TIMER_T *) NU_MODBASE(timer0hires_modinit.modname)); uint32_t prescale_timer0 = clk_timer0 / TMR0HIRES_CLK_PER_SEC - 1; MBED_ASSERT((prescale_timer0 != (uint32_t) -1) && prescale_timer0 <= 127); MBED_ASSERT((clk_timer0 % TMR0HIRES_CLK_PER_SEC) == 0); uint32_t cmp_timer0 = TMR0HIRES_CLK_PER_TMR0HIRES_INT; MBED_ASSERT(cmp_timer0 >= TMR_CMP_MIN && cmp_timer0 <= TMR_CMP_MAX); // NOTE: TIMER_CTL_CNTDATEN_Msk exists in NUC472, but not in M451. In M451, TIMER_CNT is updated continuously by default. ((TIMER_T *) NU_MODBASE(timer0hires_modinit.modname))->CTL = TIMER_PERIODIC_MODE | prescale_timer0/* | TIMER_CTL_CNTDATEN_Msk*/; ((TIMER_T *) NU_MODBASE(timer0hires_modinit.modname))->CMP = cmp_timer0; NVIC_SetVector(timer0hires_modinit.irq_n, (uint32_t) timer0hires_modinit.var); NVIC_SetVector(timer1hires_modinit.irq_n, (uint32_t) timer1hires_modinit.var); NVIC_EnableIRQ(timer0hires_modinit.irq_n); NVIC_EnableIRQ(timer1hires_modinit.irq_n); TIMER_EnableInt((TIMER_T *) NU_MODBASE(timer0hires_modinit.modname)); TIMER_Start((TIMER_T *) NU_MODBASE(timer0hires_modinit.modname)); }
void us_ticker_init(void) { if (ticker_inited) { /* By HAL spec, ticker_init allows the ticker to keep counting and disables the * ticker interrupt. */ us_ticker_disable_interrupt(); return; } ticker_inited = 1; // Reset IP SYS_ResetModule(TIMER_MODINIT.rsetidx); // Select IP clock source CLK_SetModuleClock(TIMER_MODINIT.clkidx, TIMER_MODINIT.clksrc, TIMER_MODINIT.clkdiv); // Enable IP clock CLK_EnableModuleClock(TIMER_MODINIT.clkidx); TIMER_T *timer_base = (TIMER_T *) NU_MODBASE(TIMER_MODINIT.modname); // Timer for normal counter uint32_t clk_timer = TIMER_GetModuleClock(timer_base); uint32_t prescale_timer = clk_timer / NU_TMRCLK_PER_SEC - 1; MBED_ASSERT((prescale_timer != (uint32_t) -1) && prescale_timer <= 127); MBED_ASSERT((clk_timer % NU_TMRCLK_PER_SEC) == 0); uint32_t cmp_timer = TMR_CMP_MAX; MBED_ASSERT(cmp_timer >= TMR_CMP_MIN && cmp_timer <= TMR_CMP_MAX); timer_base->CTL = TIMER_CONTINUOUS_MODE; timer_base->PRECNT = prescale_timer; timer_base->CMPR = cmp_timer; NVIC_SetVector(TIMER_MODINIT.irq_n, (uint32_t) TIMER_MODINIT.var); NVIC_DisableIRQ(TIMER_MODINIT.irq_n); TIMER_EnableInt(timer_base); TIMER_Start(timer_base); /* Wait for timer to start counting and raise active flag */ while(! (timer_base->CTL & TIMER_CTL_TMR_ACT_Msk)); }
static void lp_ticker_arm_cd(void) { TIMER_T * timer3_base = (TIMER_T *) NU_MODBASE(timer3_modinit.modname); // Reset 8-bit PSC counter, 24-bit up counter value and CNTEN bit timer3_base->CTL |= TIMER_CTL_RSTCNT_Msk; // One-shot mode, Clock = 1 KHz uint32_t clk_timer3 = TIMER_GetModuleClock((TIMER_T *) NU_MODBASE(timer3_modinit.modname)); uint32_t prescale_timer3 = clk_timer3 / TMR3_CLK_FREQ - 1; MBED_ASSERT((prescale_timer3 != (uint32_t) -1) && prescale_timer3 <= 127); timer3_base->CTL &= ~(TIMER_CTL_OPMODE_Msk | TIMER_CTL_PSC_Msk | TIMER_CTL_CNTDATEN_Msk); timer3_base->CTL |= TIMER_ONESHOT_MODE | prescale_timer3 | TIMER_CTL_CNTDATEN_Msk; cd_minor_ms = cd_major_minor_ms; cd_minor_ms = NU_CLAMP(cd_minor_ms, TMR_CMP_MIN * MS_PER_TMR3_CLK, TMR_CMP_MAX * MS_PER_TMR3_CLK); timer3_base->CMP = cd_minor_ms / MS_PER_TMR3_CLK; TIMER_EnableInt(timer3_base); TIMER_EnableWakeup((TIMER_T *) NU_MODBASE(timer3_modinit.modname)); TIMER_Start(timer3_base); }
static void us_ticker_arm_cd(void) { TIMER_T * timer1_base = (TIMER_T *) NU_MODBASE(timer1hires_modinit.modname); cd_minor_us = cd_major_minor_us; // Reset 8-bit PSC counter, 24-bit up counter value and CNTEN bit timer1_base->CTL |= TIMER_CTL_RSTCNT_Msk; // One-shot mode, Clock = 1 MHz uint32_t clk_timer1 = TIMER_GetModuleClock((TIMER_T *) NU_MODBASE(timer1hires_modinit.modname)); uint32_t prescale_timer1 = clk_timer1 / TMR1HIRES_CLK_PER_SEC - 1; MBED_ASSERT((prescale_timer1 != (uint32_t) -1) && prescale_timer1 <= 127); MBED_ASSERT((clk_timer1 % TMR1HIRES_CLK_PER_SEC) == 0); // NOTE: TIMER_CTL_CNTDATEN_Msk exists in NUC472, but not in M451. In M451, TIMER_CNT is updated continuously by default. timer1_base->CTL &= ~(TIMER_CTL_OPMODE_Msk | TIMER_CTL_PSC_Msk/* | TIMER_CTL_CNTDATEN_Msk*/); timer1_base->CTL |= TIMER_ONESHOT_MODE | prescale_timer1/* | TIMER_CTL_CNTDATEN_Msk*/; uint32_t cmp_timer1 = cd_minor_us / US_PER_TMR1HIRES_CLK; cmp_timer1 = NU_CLAMP(cmp_timer1, TMR_CMP_MIN, TMR_CMP_MAX); timer1_base->CMP = cmp_timer1; TIMER_EnableInt(timer1_base); TIMER_Start(timer1_base); }
uint32_t HardwareTimer::getModuleClock(){ return TIMER_GetModuleClock(dev); }