Пример #1
0
static bool lapic_tmr_init(tmr_cb_t master) {
    if(intr_state())
        fatal("interrupts may not be enabled in lapic_tmr_init()!\n");

    _master = master;

    // fastest possible rate: 0xB (1011) -> FSB tick rate. on modern
    // systems, this should allow near nanoseconds resolution.
    APIC_REG(APIC_REG_DIVIDE_CONFIG) = 0xB;
    uint8_t old_rate = rtc_set_rate(RTC_RATE_128HZ);
    rtc_calibrate(lapic_tmr_calibrate);

    // enable interrupts for this to work, disable the again afterwards.
    intr_enable(true);

    // wait for calibration to finish.
    while(!_lapic_hz)
        asm volatile("hlt");

    intr_disable();

    rtc_set_rate(old_rate);

    info("local apic timer calibrated to %ld hz\n", _lapic_hz);

    intr_add(IRQ_LAPIC_TIMER, lapic_tmr_handler);
    APIC_REG(APIC_REG_LVT_TIMER) = IRQ_LAPIC_TIMER;

    return true;
}
Пример #2
0
/* Init RTC */
void rtc_init_osc(int use_32khz)
{
	__use_32khz = use_32khz;

	if (use_32khz)
	{
		uint32_t old;

		/* You have to hold its hand with this one */
		/* once you start the 32KHz crystal it can only be
		 * stopped with a reset (hard or soft). */

		/* first, disable the ring osc */
		CRM->RINGOSC_CNTLbits.ROSC_EN = 0;

		/* enable the 32kHZ crystal */
		CRM->XTAL32_CNTLbits.XTAL32_EN = 1;

		/* set the XTAL32_EXISTS bit */
		/* the datasheet says to do this after you check that RTC_COUNT
		   is changing, but it is not correct; it needs to be set first */
		CRM->SYS_CNTLbits.XTAL32_EXISTS = 1;
		{
			old = CRM->RTC_COUNT;
			while (CRM->RTC_COUNT == old)
				continue;

			/* RTC has started up */
			CRM->SYS_CNTLbits.XTAL32_EXISTS = 1;
			rtc_freq = 32000;
		}
	}
	else
	{
		/* Enable ring osc */
		CRM->RINGOSC_CNTLbits.ROSC_EN = 1;
		CRM->XTAL32_CNTLbits.XTAL32_EN = 0;

		/* Set default tune values from datasheet */
		CRM->RINGOSC_CNTLbits.ROSC_CTUNE = 0x6;
		CRM->RINGOSC_CNTLbits.ROSC_FTUNE = 0x17;

		/* Trigger calibration */
		rtc_calibrate();
	}
}