/*************************************************************************//** *****************************************************************************/ void HAL_TimerInit(void) { halTimerIrqCount = 0; PM->APBCMASK.reg |= PM_APBCMASK_TC4; GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_ID(0x15/*TC4,TC5*/) | GCLK_CLKCTRL_GEN(0); SYSTIMER.CTRLA.reg = TC_CTRLA_MODE(TC_CTRLA_MODE_COUNT16_Val) | TC_CTRLA_WAVEGEN(TC_CTRLA_WAVEGEN_MFRQ_Val) | TC_CTRLA_PRESCALER(3 /*DIV8*/) | TC_CTRLA_PRESCSYNC(TC_CTRLA_PRESCSYNC_PRESC_Val); halTimerSync(); SYSTIMER.COUNT.reg = 0; halTimerSync(); SYSTIMER.CC[0].reg = TIMER_TOP; halTimerSync(); SYSTIMER.CTRLA.reg = TC_CTRLA_ENABLE; halTimerSync(); SYSTIMER.INTENSET.reg = TC_INTENSET_MC(0); NVIC_EnableIRQ(TC4_IRQn); }
void us_ticker_init(void) { uint32_t cycles_per_us; uint32_t prescaler = 0; struct tc_config config_tc; enum status_code ret_status; if (us_ticker_inited) return; us_ticker_inited = 1; if (g_sys_init == 0) { system_init(); g_sys_init = 1; } tc_get_config_defaults(&config_tc); cycles_per_us = system_gclk_gen_get_hz(config_tc.clock_source) / 1000000; MBED_ASSERT(cycles_per_us > 0); /*while((cycles_per_us & 1) == 0 && prescaler <= 10) { cycles_per_us = cycles_per_us >> 1; prescaler++; }*/ while((cycles_per_us > 1) && (prescaler <= 10)) { cycles_per_us = cycles_per_us >> 1; prescaler++; } if (prescaler >= 9) { prescaler = 7; } else if (prescaler >= 7) { prescaler = 6; } else if (prescaler >= 5) { prescaler = 5; } config_tc.clock_prescaler = TC_CTRLA_PRESCALER(prescaler); config_tc.counter_size = TC_COUNTER_SIZE_32BIT; config_tc.run_in_standby = true; config_tc.counter_32_bit.value = 0; config_tc.counter_32_bit.compare_capture_channel[TC_COMPARE_CAPTURE_CHANNEL_0] = 0xFFFFFFFF; config_tc.counter_32_bit.compare_capture_channel[TC_COMPARE_CAPTURE_CHANNEL_1] = 0xFFFFFFFF; /* Initialize the timer */ ret_status = tc_init(&us_ticker_module, TICKER_COUNTER_uS, &config_tc); MBED_ASSERT(ret_status == STATUS_OK); /* Register callback function */ tc_register_callback(&us_ticker_module, (tc_callback_t)us_ticker_irq_handler_internal, TC_CALLBACK_CC_CHANNEL0); /* Enable the timer module */ tc_enable(&us_ticker_module); }
/** * @brief Setup the given timer */ int timer_init(tim_t dev, unsigned long freq, timer_cb_t cb, void *arg) { /* at the moment, the timer can only run at 1MHz */ if (freq != 1000000ul) { return -1; } /* configure GCLK0 to feed TC0 & TC1*/; GCLK->PCHCTRL[TC0_GCLK_ID].reg |= GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN_GCLK0; while (!(GCLK->PCHCTRL[TC0_GCLK_ID].reg & GCLK_PCHCTRL_CHEN)) {} /* select the timer and enable the timer specific peripheral clocks */ switch (dev) { #if TIMER_0_EN case TIMER_0: if (TIMER_0_DEV.CTRLA.bit.ENABLE) { return 0; } MCLK->APBCMASK.reg |= MCLK_APBCMASK_TC0; /* reset timer */ TIMER_0_DEV.CTRLA.bit.SWRST = 1; while (TIMER_0_DEV.SYNCBUSY.bit.SWRST) {} TIMER_0_DEV.CTRLA.reg |= TC_CTRLA_MODE_COUNT32 | /* choosing 32 bit mode */ TC_CTRLA_PRESCALER(4) | /* sourced by 4MHz with Presc 4 results in 1MHz*/ TC_CTRLA_PRESCSYNC_RESYNC; /* initial prescaler resync */ break; #endif case TIMER_UNDEFINED: default: return -1; } /* save callback */ config[dev].cb = cb; config[dev].arg = arg; /* enable interrupts for given timer */ _irq_enable(dev); timer_start(dev); return 0; }