static void generic_or1k_clock_initialize(void) { uint64_t frequency = (1000000000 / OR1K_CLOCK_CYCLE_TIME_NANOSECONDS); uint32_t TTMR; /* For TTMR register, * The least significant 28 bits are the number of clock cycles * before generating a tick timer interrupt. While the most * significant 4 bits are used for mode configuration, tick timer * interrupt enable and pending interrupts status. */ /* FIXME: Long interval should pass since initializing the tick timer * registers fires exceptions dispite interrupts has not been enabled yet. */ TTMR = (CPU_OR1K_SPR_TTMR_MODE_RESTART | CPU_OR1K_SPR_TTMR_IE | (0xFFED9 & CPU_OR1K_SPR_TTMR_TP_MASK) ) & ~(CPU_OR1K_SPR_TTMR_IP); _OR1K_mtspr(CPU_OR1K_SPR_TTMR, TTMR); _OR1K_mtspr(CPU_OR1K_SPR_TTCR, 0); /* Initialize timecounter */ or1ksim_tc.tc_get_timecount = or1ksim_get_timecount; or1ksim_tc.tc_counter_mask = 0xffffffff; or1ksim_tc.tc_frequency = frequency; or1ksim_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER; rtems_timecounter_install(&or1ksim_tc); }
static void qoriq_clock_initialize(void) { uint32_t timer_frequency = BSP_bus_frequency / 8; uint32_t interval = (uint32_t) (((uint64_t) timer_frequency * (uint64_t) rtems_configuration_get_microseconds_per_tick()) / 1000000); qoriq_clock->bcr = GTBCR_COUNT(interval); qoriq_timecounter->bcr = GTBCR_COUNT(0xffffffff); qoriq_clock_tc.tc_get_timecount = qoriq_clock_get_timecount; qoriq_clock_tc.tc_counter_mask = GTCCR_COUNT_GET(0xffffffff); qoriq_clock_tc.tc_frequency = timer_frequency; qoriq_clock_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER; rtems_timecounter_install(&qoriq_clock_tc); }
static void riscv_generic_clock_initialize(void) { uint32_t mtimecmp = TTMR_NUM_OF_CLOCK_TICKS_INTERRUPT; uint64_t frequency = (1000000000 / RISCV_CLOCK_CYCLE_TIME_NANOSECONDS); REG(MTIME_MM) = 0; REG(MTIMECMP_MM) = TTMR_NUM_OF_CLOCK_TICKS_INTERRUPT; /* Enable mtimer interrupts */ set_csr(mie, MIP_MTIP); set_csr(mip, MIP_MTIP); /* Initialize timecounter */ riscv_generic_tc.tc_get_timecount = riscv_generic_get_timecount; riscv_generic_tc.tc_counter_mask = 0xffffffff; riscv_generic_tc.tc_frequency = frequency; riscv_generic_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER; rtems_timecounter_install(&riscv_generic_tc); }
static void t32mppc_clock_initialize(void) { uint64_t frequency = bsp_time_base_frequency / 10; uint32_t us_per_tick = rtems_configuration_get_microseconds_per_tick(); uint32_t interval = (uint32_t) ((frequency * us_per_tick) / 1000000); PPC_SET_SPECIAL_PURPOSE_REGISTER(BOOKE_DECAR, interval - 1); PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS( BOOKE_TCR, BOOKE_TCR_DIE | BOOKE_TCR_ARE ); ppc_set_decrementer_register(interval - 1); t32mppc_clock_tc.tc_get_timecount = t32mppc_clock_get_timecount; t32mppc_clock_tc.tc_counter_mask = 0xffffffff; t32mppc_clock_tc.tc_frequency = bsp_time_base_frequency; t32mppc_clock_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER; rtems_timecounter_install(&t32mppc_clock_tc); }
static void lpc_clock_initialize(void) { uint64_t interval = ((uint64_t) LPC_CLOCK_REFERENCE * (uint64_t) rtems_configuration_get_microseconds_per_tick()) / 1000000; /* Enable module */ LPC_CLOCK_MODULE_ENABLE(); /* Reset timer */ lpc_clock->tcr = LPC_TIMER_TCR_RST; /* Clear interrupt flags */ lpc_clock->ir = LPC_TIMER_IR_ALL; /* Set timer mode */ lpc_clock->ccr = 0; /* Timer is incremented every PERIPH_CLK tick */ lpc_clock->pr = 0; /* Set match registers */ lpc_clock->mr0 = (uint32_t) interval; /* Generate interrupt and reset counter on match with MR0 */ lpc_clock->mcr = LPC_TIMER_MCR_MR0_INTR | LPC_TIMER_MCR_MR0_RST; /* No external match */ lpc_clock->emr = 0x0; /* Enable timer */ lpc_clock->tcr = LPC_TIMER_TCR_EN; /* Install timecounter */ lpc_clock_tc.tc_get_timecount = lpc_clock_tc_get_timecount; lpc_clock_tc.tc_counter_mask = 0xffffffff; lpc_clock_tc.tc_frequency = LPC_CLOCK_REFERENCE; lpc_clock_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER; rtems_timecounter_install(&lpc_clock_tc); }
static void _ARMV7M_Systick_initialize(void) { volatile ARMV7M_DWT *dwt = _ARMV7M_DWT; volatile ARMV7M_Systick *systick = _ARMV7M_Systick; #ifdef BSP_ARMV7M_SYSTICK_FREQUENCY uint64_t freq = BSP_ARMV7M_SYSTICK_FREQUENCY; #else uint64_t freq = ARMV7M_SYSTICK_CALIB_TENMS_GET(systick->calib) * 100ULL; #endif uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick(); uint64_t interval = (freq * us_per_tick) / 1000000ULL; uint32_t dwt_ctrl; systick->rvr = (uint32_t) interval; systick->cvr = 0; systick->csr = ARMV7M_SYSTICK_CSR_ENABLE | ARMV7M_SYSTICK_CSR_TICKINT | ARMV7M_SYSTICK_CSR_CLKSOURCE; dwt_ctrl = dwt->ctrl; if ((dwt_ctrl & ARMV7M_DWT_CTRL_NOCYCCNT) == 0) { dwt->ctrl = dwt_ctrl | ARMV7M_DWT_CTRL_CYCCNTENA; _ARMV7M_TC.base.tc.tc_get_timecount = _ARMV7M_TC_dwt_get_timecount; _ARMV7M_TC.base.tc.tc_counter_mask = 0xffffffff; _ARMV7M_TC.base.tc.tc_frequency = freq; _ARMV7M_TC.base.tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER; _ARMV7M_TC.tick = _ARMV7M_TC_dwt_tick; rtems_timecounter_install(&_ARMV7M_TC.base.tc); } else { _ARMV7M_TC.tick = _ARMV7M_TC_systick_tick; rtems_timecounter_simple_install( &_ARMV7M_TC.base, freq, interval, _ARMV7M_TC_systick_get_timecount ); } }
rtems_device_driver Clock_initialize( rtems_device_major_number major, rtems_device_minor_number minor, void *arg ) { uint64_t frequency = bsp_time_base_frequency; uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick(); uint32_t interval = (uint32_t) ((frequency * us_per_tick) / 1000000); /* * Set default ticker. */ ppc_clock_tick = rtems_timecounter_tick; if (ppc_cpu_is_bookE() != PPC_BOOKE_405) { /* Decrementer value */ ppc_clock_decrementer_value = interval - 1; /* Check decrementer value */ if (ppc_clock_decrementer_value == 0) { ppc_clock_decrementer_value = PPC_CLOCK_DECREMENTER_MAX; RTEMS_SYSLOG_ERROR( "decrementer value would be zero, will be set to maximum value instead\n"); } if (ppc_cpu_is_bookE()) { /* Set decrementer auto-reload value */ PPC_SET_SPECIAL_PURPOSE_REGISTER( BOOKE_DECAR, ppc_clock_decrementer_value); /* Install exception handler */ ppc_exc_set_handler( ASM_BOOKE_DEC_VECTOR, ppc_clock_exception_handler_booke); /* Enable decrementer and auto-reload */ PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS( BOOKE_TCR, BOOKE_TCR_DIE | BOOKE_TCR_ARE); } else { /* Here the decrementer value is actually the interval */ ++ppc_clock_decrementer_value; /* Initialize next time base */ ppc_clock_next_time_base = ppc_time_base() + ppc_clock_decrementer_value; /* Install exception handler */ ppc_exc_set_handler( ASM_DEC_VECTOR, ppc_clock_exception_handler_first); } /* Set the decrementer value */ ppc_set_decrementer_register( ppc_clock_decrementer_value); } else { /* PIT interval value */ ppc_clock_decrementer_value = interval; /* Install exception handler */ ppc_exc_set_handler(ASM_BOOKE_DEC_VECTOR, ppc_clock_exception_handler_ppc405); /* Enable PIT and auto-reload */ PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS(PPC405_TCR, BOOKE_TCR_DIE | BOOKE_TCR_ARE); /* Set PIT auto-reload and initial value */ PPC_SET_SPECIAL_PURPOSE_REGISTER(PPC405_PIT, interval); } /* Install timecounter */ ppc_tc.tc_get_timecount = ppc_get_timecount; ppc_tc.tc_counter_mask = 0xffffffff; ppc_tc.tc_frequency = frequency; ppc_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER; rtems_timecounter_install(&ppc_tc); return RTEMS_SUCCESSFUL; }
/** * @brief Initialize the HW peripheral for clock driver * * Clock driver is implemented by RTI module * * @retval Void */ static void tms570_clock_driver_support_initialize_hardware( void ) { uint32_t microsec_per_tick; uint32_t tc_frequency; uint32_t tc_prescaler; uint32_t tc_increments_per_tick; microsec_per_tick = rtems_configuration_get_microseconds_per_tick(); tc_frequency = TMS570_PREFERRED_TC_FREQUENCY; rtems_counter_initialize_converter(BSP_PLL_OUT_CLOCK); tc_prescaler = (BSP_PLL_OUT_CLOCK + tc_frequency) / (tc_frequency * 2); /* Recompute actual most close frequency which can be realized */ tc_frequency = (BSP_PLL_OUT_CLOCK + tc_prescaler) / (tc_prescaler * 2); /* * Recompute tick period to adjust for configurable or exact * preferred time base 1 usec resolution. */ tc_increments_per_tick = ((uint64_t)microsec_per_tick * tc_frequency + 500000) / 1000000; /* Hardware specific initialize */ TMS570_RTI.GCTRL = 0; TMS570_RTI.CNT[0].CPUCx = tc_prescaler - 1; TMS570_RTI.TBCTRL = TMS570_RTI_TBCTRL_INC; TMS570_RTI.CAPCTRL = 0; TMS570_RTI.COMPCTRL = 0; /* set counter to zero */ TMS570_RTI.CNT[0].UCx = 0; TMS570_RTI.CNT[0].FRCx = 0; /* clear interrupts*/ TMS570_RTI.CLEARINTENA = TMS570_RTI_CLEARINTENA_CLEAROVL1INT | TMS570_RTI_CLEARINTENA_CLEAROVL0INT | TMS570_RTI_CLEARINTENA_CLEARTBINT | TMS570_RTI_CLEARINTENA_CLEARDMA3 | TMS570_RTI_CLEARINTENA_CLEARDMA2 | TMS570_RTI_CLEARINTENA_CLEARDMA1 | TMS570_RTI_CLEARINTENA_CLEARDMA0 | TMS570_RTI_CLEARINTENA_CLEARINT3 | TMS570_RTI_CLEARINTENA_CLEARINT2 | TMS570_RTI_CLEARINTENA_CLEARINT1 | TMS570_RTI_CLEARINTENA_CLEARINT0; TMS570_RTI.INTFLAG = TMS570_RTI_INTFLAG_OVL1INT | TMS570_RTI_INTFLAG_OVL0INT | TMS570_RTI_INTFLAG_TBINT | TMS570_RTI_INTFLAG_INT3 | TMS570_RTI_INTFLAG_INT2 | TMS570_RTI_INTFLAG_INT1 | TMS570_RTI_INTFLAG_INT0; /* set timer */ TMS570_RTI.CMP[0].COMPx = TMS570_RTI.CNT[0].FRCx + tc_increments_per_tick; TMS570_RTI.COMP0CLR = TMS570_RTI.CMP[0].COMPx + tc_increments_per_tick / 2; TMS570_RTI.CMP[0].UDCPx = tc_increments_per_tick; /* enable interupt */ TMS570_RTI.SETINTENA = TMS570_RTI_SETINTENA_SETINT0; /* enable timer */ TMS570_RTI.GCTRL = TMS570_RTI_GCTRL_CNT0EN; /* set timecounter */ tms570_rti_tc.tc_get_timecount = tms570_rti_get_timecount; tms570_rti_tc.tc_counter_mask = 0xffffffff; tms570_rti_tc.tc_frequency = tc_frequency; tms570_rti_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER; rtems_timecounter_install(&tms570_rti_tc); }