Exemplo n.º 1
0
/*!
 * @brief FTM interrupt handler.
 */
void BOARD_FTM_IRQ_HANDLER(void)
{
    // The overflow interrupt is the start of each cycle and is handled first.
    if(FTM_HAL_HasTimerOverflowed(BOARD_FTM_BASE))
    {
        // Clear the interrupt.
        FTM_HAL_ClearTimerOverflow(BOARD_FTM_BASE);

        // Update LED state/duty cycle for the X-axis.
        FTM_HAL_SetChnCountVal(BOARD_FTM_BASE, BOARD_FTM_X_CHANNEL, g_xValue);

        // Only turn on the LED if the new duty cycle is not 0.
        if(g_xValue)
        {
            LED3_ON;
            FTM_HAL_EnableChnInt(BOARD_FTM_BASE, BOARD_FTM_X_CHANNEL);
        }
        else
        {
            LED3_OFF;
            FTM_HAL_DisableChnInt(BOARD_FTM_BASE, BOARD_FTM_X_CHANNEL);
        }

        // Update LED state/duty cycle for the Y-axis.
        FTM_HAL_SetChnCountVal(BOARD_FTM_BASE, BOARD_FTM_Y_CHANNEL, g_yValue);

        // Only turn on the LED if the new duty cycle is not 0.
        if(g_yValue)
        {
            LED2_ON;
            FTM_HAL_EnableChnInt(BOARD_FTM_BASE, BOARD_FTM_Y_CHANNEL);
        }
        else
        {
            LED2_OFF;
            FTM_HAL_DisableChnInt(BOARD_FTM_BASE, BOARD_FTM_Y_CHANNEL);
        }

        // Perform a software sync to update the counter registers.
        FTM_HAL_SetSoftwareTriggerCmd(BOARD_FTM_BASE, true);
    }

    // X-axis match: Clear interrupt and turn LED off.
    if(FTM_HAL_HasChnEventOccurred(BOARD_FTM_BASE, BOARD_FTM_X_CHANNEL))
    {
        FTM_HAL_ClearChnEventFlag(BOARD_FTM_BASE, BOARD_FTM_X_CHANNEL);
        LED3_OFF;
    }

    // Y-axis match: Clear interrupt and turn LED off.
    if(FTM_HAL_HasChnEventOccurred(BOARD_FTM_BASE, BOARD_FTM_Y_CHANNEL))
    {
        FTM_HAL_ClearChnEventFlag(BOARD_FTM_BASE, BOARD_FTM_Y_CHANNEL);
        LED2_OFF;
    }
}
Exemplo n.º 2
0
void FTM_DRV_IRQHandler(uint8_t instance)
{
    uint32_t ftmBaseAddr = g_ftmBaseAddr[instance];

    /* Clear the Status flag if the interrupt is enabled */
    if (FTM_HAL_IsOverflowIntEnabled(ftmBaseAddr))
    {
        FTM_HAL_ClearTimerOverflow(ftmBaseAddr);
    }
}
Exemplo n.º 3
0
static void ResetFTM(uint32_t instance) {
  FTM_Type *ftmBase = g_ftmBase[instance];
  uint8_t channel;

  /* reset all values */
  FTM_HAL_SetCounter(ftmBase, 0); /* reset FTM counter */
  FTM_HAL_ClearTimerOverflow(ftmBase); /* clear timer overflow flag (if any) */
  for(channel=0; channel<NOF_FTM_CHANNELS; channel++) {
    FTM_HAL_ClearChnEventFlag(ftmBase, channel); /* clear channel flag */
    FTM_HAL_SetChnDmaCmd(ftmBase, channel, true); /* enable DMA request */
    FTM_HAL_EnableChnInt(ftmBase, channel); /* enable channel interrupt: need to have both DMA and CHnIE set for DMA transfers! See RM 40.4.23 */
  }
}
Exemplo n.º 4
0
static void StopFTMDMA(uint32_t instance) {
  FTM_Type *ftmBase = g_ftmBase[instance];
  uint8_t channel;

  StartStopFTM(instance, false); /* stop FTM timer */
  /* reset all values */
  FTM_HAL_SetCounter(ftmBase, 0); /* reset FTM counter */
  FTM_HAL_ClearTimerOverflow(ftmBase); /* clear timer overflow flag (if any) */
  for(channel=0; channel<NOF_FTM_CHANNELS; channel++) {
    FTM_HAL_DisableChnInt(ftmBase, channel); /* disable channel interrupt */
    FTM_HAL_SetChnDmaCmd(ftmBase, channel, false); /* disable DMA request */
    FTM_HAL_ClearChnEventFlag(ftmBase, channel); /* clear channel flag */
  }
}
/*FUNCTION**********************************************************************
 *
 * Function Name : FTM_DRV_IRQHandler
 * Description   : Initializes the Real Time Clock module
 * This function will initialize the Real Time Clock module.
 *
 *END**************************************************************************/
void FTM_DRV_IRQHandler(uint32_t instance)
{
    FTM_Type *ftmBase = g_ftmBase[instance];
    uint16_t channel;

    /* Clear the Status flag if the interrupt is enabled */
    if (FTM_HAL_IsOverflowIntEnabled(ftmBase))
    {
        FTM_HAL_ClearTimerOverflow(ftmBase);
    }

    for (channel = 0; channel < g_ftmChannelCount[instance]; channel++)
    {
        if (FTM_HAL_IsChnIntEnabled(ftmBase, channel))
        {
            FTM_HAL_ClearChnEventStatus(ftmBase, channel);
        }
    }
}
/*FUNCTION**********************************************************************
 *
 * Function Name : FTM_DRV_CounterStart
 * Description   : Starts the FTM counter. This function provides access to the
 * FTM counter. The counter can be run in Up-counting and Up-down counting modes.
 * To run the counter in Free running mode, choose Up-counting option and provide
 * 0x0 for the countStartVal and 0xFFFF for countFinalVal.
 *
 *END**************************************************************************/
void FTM_DRV_CounterStart(uint32_t instance, ftm_counting_mode_t countMode, uint32_t countStartVal,
                                 uint32_t countFinalVal, bool enableOverflowInt)
{
    assert(instance < FTM_INSTANCE_COUNT);

    FTM_Type *ftmBase = g_ftmBase[instance];
    uint32_t channel = 0;

    /* Clear the overflow flag */
    FTM_HAL_ClearTimerOverflow(ftmBase);
    FTM_HAL_SetCounterInitVal(ftmBase, countStartVal);
    FTM_HAL_SetMod(ftmBase, countFinalVal);
    FTM_HAL_SetCounter(ftmBase, 0);

    /* Use FTM as counter, disable all the channels */
    for (channel = 0; channel < g_ftmChannelCount[instance]; channel++)
    {
        FTM_HAL_SetChnEdgeLevel(ftmBase, channel, 0);
    }

    if (countMode == kCounting_FTM_UP)
    {
        FTM_HAL_SetQuadDecoderCmd(ftmBase, false);
        FTM_HAL_SetCpwms(ftmBase, 0);
    }
    else if (countMode == kCounting_FTM_UpDown)
    {
        FTM_HAL_SetQuadDecoderCmd(ftmBase, false);
        FTM_HAL_SetCpwms(ftmBase, 1);
    }

    /* Activate interrupts if required */
    FTM_DRV_SetTimeOverflowIntCmd(instance, enableOverflowInt);

    /* Set clock source to start the counter */
    FTM_HAL_SetClockSource(ftmBase, s_ftmClockSource);
}
Exemplo n.º 7
0
void FTM_DRV_CounterStart(uint8_t instance, ftm_counting_mode_t countMode, uint32_t countStartVal,
                                 uint32_t countFinalVal, bool enableOverflowInt)
{
    assert(instance < HW_FTM_INSTANCE_COUNT);

    uint32_t ftmBaseAddr = g_ftmBaseAddr[instance];
    uint32_t channel = 0;

    /* Clear the overflow flag */
    FTM_HAL_ClearTimerOverflow(ftmBaseAddr);
    FTM_HAL_SetCounterInitVal(ftmBaseAddr, countStartVal);
    FTM_HAL_SetMod(ftmBaseAddr, countFinalVal);
    FTM_HAL_SetCounter(ftmBaseAddr, 0);

    /* Use FTM as counter, disable all the channels */
    for (channel = 0; channel < FSL_FEATURE_FTM_CHANNEL_COUNTn(instance); channel++)
    {
        FTM_HAL_SetChnEdgeLevel(ftmBaseAddr, channel, 0);
    }

    if (countMode == kCounting_FTM_UP)
    {
        FTM_HAL_SetQuadDecoderCmd(ftmBaseAddr, false);
        FTM_HAL_SetCpwms(ftmBaseAddr, 0);
    }
    else if (countMode == kCounting_FTM_UpDown)
    {
        FTM_HAL_SetQuadDecoderCmd(ftmBaseAddr, false);
        FTM_HAL_SetCpwms(ftmBaseAddr, 1);
    }

    /* Activate interrupts if required */
    FTM_DRV_SetTimeOverflowIntCmd(instance, enableOverflowInt);

    /* Set clock source to start the counter */
    FTM_HAL_SetClockSource(ftmBaseAddr, kClock_source_FTM_SystemClk);
}
/*FUNCTION**********************************************************************
 *
 * Function Name : FTM_DRV_PwmStart
 * Description   : Configures duty cycle and frequency and starts outputting
 * PWM on specified channel .
 *
 *END**************************************************************************/
ftm_status_t FTM_DRV_PwmStart(uint32_t instance, ftm_pwm_param_t *param, uint8_t channel)
{
    uint32_t uFTMhz;
    uint16_t uMod, uCnv, uCnvFirstEdge = 0;

    assert(instance < FTM_INSTANCE_COUNT);
    assert(param->uDutyCyclePercent <= 100);
    assert(channel < g_ftmChannelCount[instance]);

    FTM_Type *ftmBase = g_ftmBase[instance];

    /* Clear the overflow flag */
    FTM_HAL_ClearTimerOverflow(ftmBase);

    FTM_HAL_EnablePwmMode(ftmBase, param, channel);

    if (s_ftmClockSource == kClock_source_FTM_None)
    {
        return kStatusFtmError;
    }

    uFTMhz = FTM_DRV_GetClock(instance);

    /* Based on Ref manual, in PWM mode CNTIN is to be set 0*/
    FTM_HAL_SetCounterInitVal(ftmBase, 0);

    switch(param->mode)
    {
        case kFtmEdgeAlignedPWM:
            uMod = uFTMhz / (param->uFrequencyHZ) - 1;
            uCnv = uMod * param->uDutyCyclePercent / 100;
            /* For 100% duty cycle */
            if(uCnv >= uMod)
            {
                uCnv = uMod + 1;
            }
            FTM_HAL_SetMod(ftmBase, uMod);
            FTM_HAL_SetChnCountVal(ftmBase, channel, uCnv);
            break;
        case kFtmCenterAlignedPWM:
            uMod = uFTMhz / (param->uFrequencyHZ * 2);
            uCnv = uMod * param->uDutyCyclePercent / 100;
            /* For 100% duty cycle */
            if(uCnv >= uMod)
            {
                uCnv = uMod + 1;
            }
            FTM_HAL_SetMod(ftmBase, uMod);
            FTM_HAL_SetChnCountVal(ftmBase, channel, uCnv);
            break;
        case kFtmCombinedPWM:
            uMod = uFTMhz / (param->uFrequencyHZ) - 1;
            uCnv = uMod * param->uDutyCyclePercent / 100;
            uCnvFirstEdge = uMod * param->uFirstEdgeDelayPercent / 100;
            /* For 100% duty cycle */
            if(uCnv >= uMod)
            {
                uCnv = uMod + 1;
            }
            FTM_HAL_SetMod(ftmBase, uMod);
            FTM_HAL_SetChnCountVal(ftmBase, FTM_HAL_GetChnPairIndex(channel) * 2,
                                   uCnvFirstEdge);
            FTM_HAL_SetChnCountVal(ftmBase, FTM_HAL_GetChnPairIndex(channel) * 2 + 1,
                                   uCnv + uCnvFirstEdge);
            break;
        default:
            assert(0);
            break;
    }

    /* Set clock source to start counter */
    FTM_HAL_SetClockSource(ftmBase, s_ftmClockSource);
    return kStatusFtmSuccess;
}
Exemplo n.º 9
0
/*See fsl_ftm_driver.h for documentation of this function.*/
void FTM_DRV_PwmStart(uint8_t instance, ftm_pwm_param_t *param, uint8_t channel)
{
    uint32_t uFTMhz;
    uint16_t uMod, uCnv, uCnvFirstEdge = 0;

    assert(instance < HW_FTM_INSTANCE_COUNT);
    assert(param->uDutyCyclePercent <= 100);
    assert(channel < FSL_FEATURE_FTM_CHANNEL_COUNTn(instance));

    uint32_t ftmBaseAddr = g_ftmBaseAddr[instance];

    /* Clear the overflow flag */
    FTM_HAL_ClearTimerOverflow(g_ftmBaseAddr[instance]);

    FTM_HAL_EnablePwmMode(ftmBaseAddr, param, channel);

#if FSL_FEATURE_FTM_BUS_CLOCK
    CLOCK_SYS_GetFreq(kBusClock, &uFTMhz);
#else
    CLOCK_SYS_GetFreq(kSystemClock, &uFTMhz);
#endif

    /* Based on Ref manual, in PWM mode CNTIN is to be set 0*/
    FTM_HAL_SetCounterInitVal(ftmBaseAddr, 0);

    uFTMhz = uFTMhz / (1 << FTM_HAL_GetClockPs(ftmBaseAddr));

    switch(param->mode)
    {
        case kFtmEdgeAlignedPWM:
            uMod = uFTMhz / (param->uFrequencyHZ) - 1;
            uCnv = uMod * param->uDutyCyclePercent / 100;
            /* For 100% duty cycle */
            if(uCnv >= uMod)
            {
                uCnv = uMod + 1;
            }
            FTM_HAL_SetMod(ftmBaseAddr, uMod);
            FTM_HAL_SetChnCountVal(ftmBaseAddr, channel, uCnv);
            break;
        case kFtmCenterAlignedPWM:
            uMod = uFTMhz / (param->uFrequencyHZ * 2);
            uCnv = uMod * param->uDutyCyclePercent / 100;
            /* For 100% duty cycle */
            if(uCnv >= uMod)
            {
                uCnv = uMod + 1;
            }
            FTM_HAL_SetMod(ftmBaseAddr, uMod);
            FTM_HAL_SetChnCountVal(ftmBaseAddr, channel, uCnv);
            break;
        case kFtmCombinedPWM:
            uMod = uFTMhz / (param->uFrequencyHZ) - 1;
            uCnv = uMod * param->uDutyCyclePercent / 100;
            uCnvFirstEdge = uMod * param->uFirstEdgeDelayPercent / 100;
            /* For 100% duty cycle */
            if(uCnv >= uMod)
            {
                uCnv = uMod + 1;
            }
            FTM_HAL_SetMod(ftmBaseAddr, uMod);
            FTM_HAL_SetChnCountVal(ftmBaseAddr, FTM_HAL_GetChnPairIndex(channel) * 2,
                                   uCnvFirstEdge);
            FTM_HAL_SetChnCountVal(ftmBaseAddr, FTM_HAL_GetChnPairIndex(channel) * 2 + 1,
                                   uCnv + uCnvFirstEdge);
            break;
        default:
            assert(0);
            break;
    }

    /* Set clock source to start counter */
    FTM_HAL_SetClockSource(ftmBaseAddr, kClock_source_FTM_SystemClk);
}