Exemple #1
0
/*!
 * @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. If the required period is a large value, then the code will try to use a low-frequency
 * external clock if available.
 *
 * 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_t structure.
 *
 * @param hwtimer[in] Pointer to hwtimer structure.
 * @param period[in] Required period of timer in micro seconds.
 *
 * @return kHwtimerSuccess      Success.
 * @return kHwtimerInvalidInput Divider is equal too big.
 *
 * @see HWTIMER_SYS_SystickInit
 * @see HWTIMER_SYS_SystickDeinit
 * @see HWTIMER_SYS_SystickStart
 * @see HWTIMER_SYS_SystickStop
 * @see HWTIMER_SYS_SystickGet_time
 * @see HWTIMER_SYS_SystickIsrAction
 */
static _hwtimer_error_code_t HWTIMER_SYS_SystickSetDiv(hwtimer_t *hwtimer, uint32_t period)
{
    assert(NULL != hwtimer);
    uint64_t divider;

#if FSL_FEATURE_SYSTICK_HAS_EXT_REF
    /* Set the clock source back to core freq */
    CLOCK_SYS_SetSystickSrc(kClockSystickSrcCore);
#endif
    /* Get Core clock frequency */
    hwtimer->clockFreq = CLOCK_SYS_GetSystickFreq();

    divider = (((uint64_t)hwtimer->clockFreq * period)) / 1000000U ;

    /* if divider is greater than 24b value we return an error */
    if ((divider - 1U) & ~SysTick_LOAD_RELOAD_Msk)
    {
#if FSL_FEATURE_SYSTICK_HAS_EXT_REF
        /* Check if we can use a slower clock source to get required period */
        CLOCK_SYS_SetSystickSrc(kClockSystickSrcExtRef);
        hwtimer->clockFreq = CLOCK_SYS_GetSystickFreq();
        divider = (((uint64_t)hwtimer->clockFreq * period)) / 1000000U ;

        if ((divider - 1U) & ~SysTick_LOAD_RELOAD_Msk)
        {
            return kHwtimerInvalidInput;
        }
#else
        return kHwtimerInvalidInput;
#endif
    }

    /*
     * A start value of 0 (divider == 1) is possible, but has no effect because the
     * SysTick interrupt and COUNTFLAG are activated when counting from 1 to 0.
     */
    if (divider == 1U)
    {
        divider = 2U; /* Set smallest possible value for divider. */
    }

    SysTick->LOAD = divider - 1U;

    /* Store in struct. */
    hwtimer->divider    = divider;
    hwtimer->modulo     = divider;

    return kHwtimerSuccess;
}
clock_manager_error_code_t CLOCK_SYS_GetFreq(clock_names_t clockName,
                                                 uint32_t *frequency)
{
    clock_manager_error_code_t returnCode = kClockManagerSuccess;

    switch (clockName)
    {
        case kCoreClock:
        case kSystemClock:
            *frequency = CLOCK_SYS_GetCoreClockFreq();
            break;
        case kPlatformClock:
            *frequency = CLOCK_SYS_GetSystemClockFreq();
            break;
        case kBusClock:
            *frequency = CLOCK_SYS_GetBusClockFreq();
            break;
        case kFlashClock:
            *frequency = CLOCK_SYS_GetFlashClockFreq();
            break;
        case kOsc32kClock:
            *frequency = CLOCK_SYS_GetExternalRefClock32kFreq();
            break;
        case kOsc0ErClock:
            *frequency = CLOCK_SYS_GetOsc0ExternalRefClockFreq();
            break;
        case kRtcoutClock:
            *frequency = CLOCK_SYS_GetRtcOutFreq();
            break;
        case kMcgFfClock:
            *frequency = CLOCK_SYS_GetFixedFreqClockFreq();
            break;
        case kMcgFllClock:
            *frequency = CLOCK_HAL_GetFllClk(MCG);
            break;
        case kMcgPll0Clock:
            *frequency = CLOCK_HAL_GetPll0Clk(MCG);
            break;
        case kMcgOutClock:
            *frequency = CLOCK_HAL_GetOutClk(MCG);
            break;
        case kMcgIrClock:
            *frequency = CLOCK_HAL_GetInternalRefClk(MCG);
            break;
        case kLpoClock:
            *frequency = CLOCK_SYS_GetLpoClockFreq();
            break;
        case kSystickClock:
            *frequency = CLOCK_SYS_GetSystickFreq();
            break;
        default:
            *frequency = 0U;
            returnCode = kClockManagerNoSuchClockName;
            break;
    }

    return returnCode;
}
Exemple #3
0
/*
** ===================================================================
**     Method      :  OSA_TimeInit (component fsl_os_abstraction)
**
**     Description :
**         This function initializes the timer used in BM OSA, the 
**         functions such as OSA_TimeDelay, OSA_TimeGetMsec, and the 
**         timeout are all based on this timer.
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
void OSA_TimeInit(void)
{
  uint64_t divider;
  
  /* Disable timer and interrupt */
  SysTick->CTRL = 0U;
  /* A write of any value to current value register clears the field to 0, and also clears the SYST_CSR COUNTFLAG bit to 0. */
  SysTick->VAL = 0U;    
#if FSL_FEATURE_SYSTICK_HAS_EXT_REF
    /* Set the clock source back to core freq */
    CLOCK_SYS_SetSystickSrc(kClockSystickSrcCore);
#endif  
  /* Get SysTick counter input frequency and compute divider value */  
  divider = ((((uint64_t)CLOCK_SYS_GetSystickFreq() * OSA1_TIMER_PERIOD_US)) / 1000000U);
  assert(divider != 0U);
  /* Set divide input clock of systick timer */
  SysTick->LOAD = (uint32_t)(divider - 1U);
  /* Set interrupt priority and enable interrupt */  
  NVIC_SetPriority(SysTick_IRQn, 7U);
  /* Run timer and enable interrupt */
  SysTick->CTRL = (SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk);  
}