/* * ======== TimestampProvider_Module_startup ======== * The Timestamp module is part of the xdc.runtime package, so all of its * APIs must be ready after the first startup pass. Clock_getTimerHandle * doesn't have any calling constraints. */ Int TimestampProvider_Module_startup(Int phase) { ti_sysbios_hal_Timer_Handle halTimer; /* * If we're sharing the Clock timer, retrieve the handle to the * underlying timer. */ if (TimestampProvider_useClockTimer) { /* Get the Clock's hal.Timer instance */ halTimer = Clock_getTimerHandle(); /* Assert that the Clock's tick source is a timer (not the user) */ Assert_isTrue((halTimer != NULL), NULL); /* Get the handle to the family.c28.Timer ("proxy instance")*/ MOD->timer = (Timer_Handle) halTimer->pi; } return (Startup_DONE); }
/* * ======== Clock_Module_startup ======== */ Int SecondsClock_Module_startup(Int phase) { Clock_TimerProxy_Handle timer; Types_FreqHz freq; UInt32 period; UInt32 absDrift; UInt32 c1, c2; Int32 drift; if (!Clock_Module_startupDone()) { return Startup_NOTDONE; } timer = Clock_getTimerHandle(); Clock_TimerProxy_getFreq(timer, &freq); period = Clock_TimerProxy_getPeriod(timer); /* * Calculate the clock drift: * * drift = timerFreq - clockFreq * clockTimerPeriod * * Example: The timer frequency is 32Khz (frequency is actually 32768), * and clock tick is 1 millisecond. The timer period register will be * set to 32. The drift is: * 32768 - 1000 * 32 = 768 * * This means that our 'second' is really short by 768 timer ticks, or * 768 / 32768 of a second. (This problem would be easily solved by just * setting the period of the SecondsClock to 1024 msecs instead of 1000 * msecs, but it serves as a simple example.) * * If the drift is negative, our seconds are too long. For example, if * the timer period register were 33 in the above example instead of 32, * we would get * drift = 32768 - 1000 * 33 = -768 * * To adjust the seconds, we will periodically add (drift > 0) or subtract * (drift < 0) a second. The period to do this will be: * * c1 = floor(timer freq / |drift|) * * In the above example (for both 32 and 33 timer periods), we will adjust * every floor(32768 / 768) = 42 seconds. * * In this example, we are adjusting a little too quickly, since * 32768 / 768 = 42 2/3. Too compensate, periodically, we will adjust by * not adding or subtracting a second. * * To calculate the period for not adjusting: Calculate what the * 2nd drift would be after the first adjustment: * * drift2 = timerFreq - c1 * |drift| * * drift2 is accumulated every c1 seconds. If drift2 != 0, set * * c2 = floor(timerFreq / drift2) * * and every c1 * c2 seconds, do not do the adjustment. * * If we wanted, we could continue in this manner, calculating * drift3 = timerFreq - c2 * |drift2| * c3 = floor(timerFreq / drift3) * * and every c1 * c2 * c3 seconds, do the adjustment. */ drift = freq.lo - (1000000 / Clock_tickPeriod) * period; absDrift = (drift < 0) ? -drift : drift; /* Only calculate drift for frequencies less than 4GHz */ if (freq.lo && drift) { c1 = c2 = 0; c1 = freq.lo / absDrift; c2 = (freq.lo != c1 * absDrift) ? freq.lo / (freq.lo - c1 * absDrift) : 0; SecondsClock_module->c1Inc = (drift > 0) ? -1 : 1; SecondsClock_module->c1 = c1; SecondsClock_module->c2 = c2; } Clock_start(SecondsClock_Module_State_clock()); return Startup_DONE; }