/*! * \cond DOXYGEN_PRIVATE * * \brief Atomically captures current time into HWTIMER_TIME_STRUCT structure * * Corrects/normalizes the values if necessary (interrupt pending, etc.) * * \param hwtimer[in] Pointer to hwtimer structure. * \param time[out] Pointer to time structure. This value is filled with current value of the timer. * * \return MQX_OK Success. * * \see hwtimer_pit_init * \see hwtimer_pit_deinit * \see hwtimer_pit_set_div * \see hwtimer_pit_start * \see hwtimer_pit_stop * \see hwtimer_pit_isr * \see hwtimer_pit_isr_shared */ static _mqx_int hwtimer_pit_get_time(HWTIMER_PTR hwtimer, HWTIMER_TIME_PTR time) { PIT_MemMapPtr pit_base = (PIT_MemMapPtr) hwtimer->ll_context[0]; uint32_t pit_channel = GET_PIT_CHANNEL_FROM_PITID(hwtimer->ll_context[1]); uint32_t temp_cval; /* Disable interrupt from timer*/ _int_disable(); time->TICKS = hwtimer->ticks; temp_cval = PIT_CVAL_REG(pit_base, pit_channel); /* Check pending interrupt flag */ if(PIT_TFLG_REG(pit_base, pit_channel) & PIT_TFLG_TIF_MASK) { _int_enable(); time->SUBTICKS = hwtimer->modulo - 1; } else { _int_enable(); time->SUBTICKS = PIT_LDVAL_REG(pit_base, pit_channel) - temp_cval; } return MQX_OK; }
/*! * \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 MQX_OK Success. * \return MQX_INVALID_PARAMETER Divider is equal to zero. * * \see hwtimer_pit_init * \see hwtimer_pit_deinit * \see hwtimer_pit_start * \see hwtimer_pit_stop * \see hwtimer_pit_get_time * \see hwtimer_pit_isr * \see hwtimer_pit_isr_shared */ static _mqx_int hwtimer_pit_set_div(HWTIMER_PTR hwtimer, uint32_t divider) { PIT_MemMapPtr pit_base = (PIT_MemMapPtr) hwtimer->ll_context[0]; uint32_t pit_channel = GET_PIT_CHANNEL_FROM_PITID(hwtimer->ll_context[1]); #if MQX_CHECK_ERRORS if (0 == divider) { return MQX_INVALID_PARAMETER; } #endif PIT_LDVAL_REG(pit_base, pit_channel) = divider - 1; hwtimer->divider = divider; hwtimer->modulo = divider; return MQX_OK; }
/*FUNCTION*----------------------------------------------------------------- * * Function Name : _kinetis_timer_init_freq * Returned Value : the clock rate for the timer (ns per hw tick) * Comments : * this function will set up a timer to interrupt * *END*---------------------------------------------------------------------*/ void _kinetis_timer_init_freq ( /* [IN] the timer to initialize */ _mqx_uint timer, /* [IN] ticks per second */ uint_32 tickfreq, /* [IN] the system clock speed in MHz */ uint_32 system_clock, /* [IN] Unmask the timer after initializing */ boolean unmask_timer ) { /* Body */ if(tickfreq != 0) { /* Enable PIT Module Clock */ SIM_SCGC6 |= SIM_SCGC6_PIT_MASK; /* Configure PIT */ PIT_MCR = ~(PIT_MCR_FRZ_MASK |PIT_MCR_MDIS_MASK); /* Timer counter value */ PIT_LDVAL_REG(PIT_BASE_PTR,timer) = system_clock/tickfreq; /* Enable PIT interrupt */ PIT_TCTRL_REG(PIT_BASE_PTR,timer) = PIT_TCTRL_TEN_MASK; /* Mask PIT interrupt flag */ PIT_TFLG_REG(PIT_BASE_PTR,timer)= PIT_TFLG_TIF_MASK; } if (unmask_timer) { _kinetis_timer_unmask_int(timer); } }