/*FUNCTION********************************************************************** * * Function Name : PIT_DRV_InitUs * Description : Initializes two PIT channels to serve as a microseconds unit. * This function is in parallel with PIT_DRV_InitChannel, they will overwrite * each other. PIT_DRV_Init must be called before calling this function. * The microseconds unit will use two chained channels to simulate a lifetime * timer, the channel number passed in and the "channel -1" channel will be used. * Note: * 1. These two channels will be occupied and could not be used with other purposes. * 2. The channel number passed in must be greater than 0. *END**************************************************************************/ void PIT_DRV_InitUs(uint32_t instance, uint32_t channel) { assert(instance < PIT_INSTANCE_COUNT); assert(channel > 0U); PIT_Type * base = g_pitBase[instance]; g_pitUsInstance = instance; g_pitUsChannel = channel; PIT_HAL_SetTimerChainCmd(base, channel, true); PIT_HAL_SetTimerPeriodByCount(base, channel, 0xFFFFFFFFU); PIT_HAL_SetTimerPeriodByCount(base, channel - 1U, 0xFFFFFFFFU); PIT_HAL_StartTimer(base, channel); PIT_HAL_StartTimer(base, channel - 1U); }
/*! * @cond DOXYGEN_PRIVATE * * @brief Sets up timer with divider settings closest to the requested period in microseconds. * * The function gets the value of the base frequency of the timer via clock manager and calculates required * divider ratio. * * Called by hwtimer_set_freq() and hwtimer_set_period(). * Fills in the divider (actual total divider) and modulo (sub-tick resolution) members of the HWTIMER structure. * * @param hwtimer[in] Pointer to hwtimer structure. * @param period[in] Required period of timer in micro seconds. * * @return kHwtimerSuccess Success. * * @see HWTIMER_SYS_PitInit * @see HWTIMER_SYS_PitDeinit * @see HWTIMER_SYS_PitStart * @see HWTIMER_SYS_PitStop * @see HWTIMER_SYS_PitGetTime * @see HWTIMER_SYS_PitIsrAction */ static _hwtimer_error_code_t HWTIMER_SYS_PitSetDiv(hwtimer_t * hwtimer, uint32_t period) { uint32_t pitChannel; PIT_Type * base = g_pitBase[0]; uint64_t divider; assert(NULL != hwtimer); /* Store clock frequency in struct. */ hwtimer->clockFreq = CLOCK_SYS_GetPitFreq(0); divider = (((uint64_t)hwtimer->clockFreq * period)) / 1000000U ; /* If required frequency is higher than input clock frequency, we set divider 1 (for setting the highest possible frequency) */ if (0U == divider) { divider = 1U; } /* if divider is greater than 32b value we set divider to max 32b value */ else if (divider & 0xFFFFFFFF00000000U) { return kHwtimerInvalidInput; } pitChannel = hwtimer->llContext[0U]; assert(pitChannel < FSL_FEATURE_PIT_TIMER_COUNT); /* Set divider for pit chanell */ PIT_HAL_SetTimerPeriodByCount(base, pitChannel, divider - 1U); hwtimer->divider = divider; hwtimer->modulo = divider; return kHwtimerSuccess; }
/*FUNCTION********************************************************************** * * Function Name : PIT_DRV_SetTimerPeriodByCount * Description : Sets the timer period in units of count. * Timers begin counting from the value set by this function. * The counter period of a running timer can be modified by first stopping * the timer, setting a new load value, and starting the timer again. If * timers are not restarted, the new value is loaded after the next trigger * event. * *END**************************************************************************/ void PIT_DRV_SetTimerPeriodByCount(uint32_t instance, uint32_t channel, uint32_t count) { assert(instance < PIT_INSTANCE_COUNT); PIT_Type * base = g_pitBase[instance]; PIT_HAL_SetTimerPeriodByCount(base, channel, count); }
/*FUNCTION********************************************************************** * * Function Name : PIT_DRV_SetTimerPeriodByUs * Description : Set timer period in microseconds unit. * The period range depends on the frequency of PIT source clock. If required * period is out the range, try to use lifetime timer if applicable. * This function is only valid for one single channel. If channels are chained together, * the period here will make no sense. * *END**************************************************************************/ void PIT_DRV_SetTimerPeriodByUs(uint32_t instance, uint32_t channel, uint32_t us) { assert(instance < PIT_INSTANCE_COUNT); PIT_Type * base = g_pitBase[instance]; /* Calculate the count value, assign it to timer counter register.*/ uint32_t count = (uint32_t)(us * g_pitSourceClock / 1000000U - 1U); PIT_HAL_SetTimerPeriodByCount(base, channel, count); }
/*! * @brief Function ltc_timer_init initialize PIT timer * to measure time. */ static void ltc_timer_init(void) { SIM_HAL_EnableClock(SIM, kSimClockGatePit0); PIT_HAL_Enable(pitBase[0]); PIT_HAL_StopTimer(pitBase[0], LTC_TIMER_PIT_CHANNEL); PIT_HAL_SetTimerPeriodByCount(pitBase[0], LTC_TIMER_PIT_CHANNEL, RELOAD); PIT_HAL_SetIntCmd(pitBase[0], LTC_TIMER_PIT_CHANNEL, false); PIT_HAL_SetTimerRunInDebugCmd(pitBase[0], false); /* timer stop counting in debug mode */ PIT_HAL_ClearIntFlag(pitBase[0], LTC_TIMER_PIT_CHANNEL); }
/*FUNCTION********************************************************************** * * Function Name : PIT_DRV_SetLifetimeTimerPeriodByUs * Description : Set lifetime timer period (Timers must be chained). * Timer 1 must be chained with timer 0 before using lifetime timer. The period * range is restricted by "period * g_pitSourceClock < max of an uint64_t integer", * or it may cause a overflow and is not able to set correct period. * *END**************************************************************************/ void PIT_DRV_SetLifetimeTimerPeriodByUs(uint32_t instance, uint64_t us) { assert(instance < PIT_INSTANCE_COUNT); PIT_Type * base = g_pitBase[instance]; uint64_t lifeTimeCount; /* Calculate the counter value.*/ lifeTimeCount = us * g_pitSourceClock / 1000000U - 1U; /* Assign to timers.*/ PIT_HAL_SetTimerPeriodByCount(base, 0U, (uint32_t)lifeTimeCount); PIT_HAL_SetTimerPeriodByCount(base, 1U, (uint32_t)(lifeTimeCount >> 32U)); }
/*! * @cond DOXYGEN_PRIVATE * * @brief Sets up timer with divider settings closest to the requested total divider factor. * * Called by hwtimer_set_freq() and hwtimer_set_period(). * Fills in the divider (actual total divider) and modulo (sub-tick resolution) members of the HWTIMER structure. * * @param hwtimer[in] Pointer to hwtimer structure. * @param divider[in] Value which divide input clock of pit timer module to obtain requested period of timer. * * @return kHwtimerSuccess Success. * * @see HWTIMER_SYS_PitInit * @see HWTIMER_SYS_PitDeinit * @see HWTIMER_SYS_PitStart * @see HWTIMER_SYS_PitStop * @see HWTIMER_SYS_PitGetTime * @see HWTIMER_SYS_PitIsr * @see HWTIMER_SYS_PitIsrShared */ static _hwtimer_error_code_t HWTIMER_SYS_PitSetDiv(hwtimer_t * hwtimer, uint32_t divider) { uint32_t pitChannel; uint32_t baseAddr = g_pitBaseAddr[0]; assert(NULL != hwtimer); assert(0U != divider); pitChannel = hwtimer->llContext[0U]; assert(pitChannel < FSL_FEATURE_PIT_TIMER_COUNT); /* Set divider for pit chanell */ PIT_HAL_SetTimerPeriodByCount(baseAddr, pitChannel, divider - 1U); hwtimer->divider = divider; hwtimer->modulo = divider; return kHwtimerSuccess; }