/*FUNCTION**********************************************************************
 *
 * Function Name : FTM_DRV_SetupChnDualEdgeCapture
 * Description   : Configures the Dual Edge Capture mode of the FTM
 * This function sets up the dual edge capture mode on a channel pair.
 * The capture edge for the channel pair and the capture mode (one-shot or continuous)
 * is specified in the param argument. The filter function is disabled if the
 * filterVal argument passed in is 0. The filter function is available only on
 * channels 0 and 2. The user will have to read the channel CnV registers separately
 * to get the capture values.
 *
 *END**************************************************************************/
void FTM_DRV_SetupChnDualEdgeCapture(uint32_t instance, ftm_dual_edge_capture_param_t *param,
                                                 uint8_t channel, uint8_t filterVal)
{
    assert(instance < FTM_INSTANCE_COUNT);
    assert(channel < g_ftmChannelCount[instance]);

    FTM_Type *ftmBase = g_ftmBase[instance];
    uint32_t chnlPairnum = FTM_HAL_GetChnPairIndex(channel);

    /* Stop the counter */
    FTM_HAL_SetClockSource(ftmBase, kClock_source_FTM_None);

    FTM_HAL_SetCounterInitVal(ftmBase, 0);
    FTM_HAL_SetMod(ftmBase, 0xFFFF);
    FTM_HAL_SetCpwms(ftmBase, 0);
    FTM_HAL_SetDualChnCombineCmd(ftmBase, chnlPairnum, false);
    /* Enable the DECAPEN bit */
    FTM_HAL_SetDualEdgeCaptureCmd(ftmBase, chnlPairnum, true);
    /* Setup the edge detection from channel n and n + 1 */
    FTM_HAL_SetChnEdgeLevel(ftmBase, chnlPairnum * 2, param->currChanEdgeMode);
    FTM_HAL_SetChnEdgeLevel(ftmBase, (chnlPairnum * 2) + 1, param->nextChanEdgeMode);

    FTM_HAL_ClearChnEventFlag(ftmBase, channel);
    FTM_HAL_ClearChnEventFlag(ftmBase, channel + 1);
    FTM_HAL_SetDualChnDecapCmd(ftmBase, chnlPairnum, true);
    FTM_HAL_SetChnMSnBAMode(ftmBase, chnlPairnum * 2, param->mode);

    if (channel < CHAN4_IDX)
    {
        FTM_HAL_SetChnInputCaptureFilter(ftmBase, channel, filterVal);
    }

    /* Set clock source to start the counter */
    FTM_HAL_SetClockSource(ftmBase, s_ftmClockSource);
}
Example #2
0
/*FUNCTION**********************************************************************
 *
 * Function Name : FTM_HAL_EnablePwmMode
 * Description   : Enables the FTM timer when it is PWM output mode
 *
 *END**************************************************************************/
void FTM_HAL_EnablePwmMode(FTM_Type *ftmBase, ftm_pwm_param_t *config, uint8_t channel)
{
    uint8_t chnlPairnum = FTM_HAL_GetChnPairIndex(channel);

    FTM_HAL_SetDualEdgeCaptureCmd(ftmBase, chnlPairnum, false);
    FTM_HAL_SetChnEdgeLevel(ftmBase, channel, config->edgeMode ? 1 : 2);
    switch(config->mode)
    {
        case kFtmEdgeAlignedPWM:
            FTM_HAL_SetDualChnCombineCmd(ftmBase, chnlPairnum, false);
            FTM_HAL_SetCpwms(ftmBase, 0);
            FTM_HAL_SetChnMSnBAMode(ftmBase, channel, 2);
            break;
        case kFtmCenterAlignedPWM:
            FTM_HAL_SetDualChnCombineCmd(ftmBase, chnlPairnum, false);
            FTM_HAL_SetCpwms(ftmBase, 1);
            break;
        case kFtmCombinedPWM:
            FTM_HAL_SetCpwms(ftmBase, 0);
            FTM_HAL_SetDualChnCombineCmd(ftmBase, chnlPairnum, true);
            break;
        default:
            assert(0);
            break;
    }
}
/*FUNCTION**********************************************************************
 *
 * Function Name : FTM_DRV_SetupChnInputCapture
 * Description   : Enables capture of an input signal on the channel using the
 * paramters specified to this function. When the edge specified in the captureMode
 * argument occurs on the channel the FTM counter is captured into the CnV register.
 * The user will have to read the CnV register separately to get this value. The filter
 * function is disabled if the filterVal argument passed in is 0. The filter function
 * is available only on channels 0,1,2,3.
 *
 *END**************************************************************************/
void FTM_DRV_SetupChnInputCapture(uint32_t instance, ftm_input_capture_edge_mode_t captureMode,
                                            uint8_t channel, uint8_t filterVal)
{
    assert(instance < FTM_INSTANCE_COUNT);
    assert(channel < g_ftmChannelCount[instance]);

    FTM_Type *ftmBase = g_ftmBase[instance];
    uint32_t chnlPairnum = FTM_HAL_GetChnPairIndex(channel);

    FTM_HAL_SetClockSource(ftmBase, kClock_source_FTM_None);

    FTM_HAL_SetCounterInitVal(ftmBase, 0);
    FTM_HAL_SetMod(ftmBase, 0xFFFF);
    FTM_HAL_SetCpwms(ftmBase, 0);
    FTM_HAL_SetDualChnCombineCmd(ftmBase, chnlPairnum, false);
    FTM_HAL_SetDualEdgeCaptureCmd(ftmBase, chnlPairnum, false);
    FTM_HAL_SetChnEdgeLevel(ftmBase, channel, captureMode);

    if (channel < CHAN4_IDX)
    {
        FTM_HAL_SetChnInputCaptureFilter(ftmBase, channel, filterVal);
    }

    FTM_HAL_SetChnMSnBAMode(ftmBase, channel, 0);

    /* Set clock source to start the counter */
    FTM_HAL_SetClockSource(ftmBase, s_ftmClockSource);
}
Example #4
0
/*FUNCTION**********************************************************************
 *
 * Function Name : FTM_HAL_DisablePwmMode
 * Description   : Disables the PWM output mode.
 *
 *END**************************************************************************/
void FTM_HAL_DisablePwmMode(FTM_Type *ftmBase, ftm_pwm_param_t *config, uint8_t channel)
{
    uint8_t chnlPairnum = FTM_HAL_GetChnPairIndex(channel);

    FTM_HAL_SetChnCountVal(ftmBase, channel, 0);
    FTM_HAL_SetChnEdgeLevel(ftmBase, channel, 0);
    FTM_HAL_SetChnMSnBAMode(ftmBase, channel, 0);
    FTM_HAL_SetCpwms(ftmBase, 0);
    FTM_HAL_SetDualChnCombineCmd(ftmBase, chnlPairnum, false);
}
/*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);
}
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 : SMARTCARD_DRV_InterfaceClockInit
 * Description   : This function initializes clock module used for card clock generation
 *
 *END**************************************************************************/
static uint16_t SMARTCARD_DRV_InterfaceClockInit(uint8_t clockModuleInstance,  uint8_t clockModuleChannel, uint32_t cardClk)
{
#if defined(EMVSIM_INSTANCE_COUNT)
    assert(clockModuleInstance < EMVSIM_INSTANCE_COUNT);
    
    EMVSIM_Type * base = g_emvsimBase[clockModuleInstance];
    uint32_t emvsimClkMhz = 0;
    uint8_t emvsimPRSCValue;
    
    /* Retrieve EMV SIM clock */
    emvsimClkMhz = CLOCK_SYS_GetEmvsimFreq(clockModuleInstance)/1000000;
    
    /* Calculate MOD value */
    emvsimPRSCValue = (emvsimClkMhz*1000)/(cardClk/1000);
    
    /* Set clock prescaler */
    EMVSIM_HAL_SetClockPrescaler(base, emvsimPRSCValue);
    
    /* Enable smart card clock */
    EMVSIM_HAL_EnableCardClock(base);
    
    return cardClk;
	
#elif defined(FTM_INSTANCE_COUNT)
    assert(clockModuleInstance < FTM_INSTANCE_COUNT);
    
    
    ftm_user_config_t ftmInfo;    
    uint32_t periph_clk_mhz = 0;
    uint16_t ftmModValue;
    FTM_Type * ftmBase = g_ftmBase[clockModuleInstance];
    uint32_t chnlPairnum = FTM_HAL_GetChnPairIndex(clockModuleChannel);
    
    /* Retrieve FTM system clock */
    periph_clk_mhz = CLOCK_SYS_GetBusClockFreq()/1000000;
    
    /* Calculate MOD value */
    ftmModValue = ((periph_clk_mhz*1000/2)/(cardClk/1000)) -1;
    
    /* Clear FTM driver user configuration */
    memset(&ftmInfo, 0, sizeof(ftmInfo));
    
    ftmInfo.BDMMode = kFtmBdmMode_11;
    ftmInfo.syncMethod = kFtmUseSoftwareTrig;
    
    /* Initialize FTM driver */
    FTM_DRV_Init(clockModuleInstance, &ftmInfo);
    
    /* Reset FTM prescaler to 'Divide by 1', i.e., to be same clock as peripheral clock  */
    FTM_HAL_SetClockPs(ftmBase, kFtmDividedBy1);
    
    /* Disable FTM counter firstly */
    FTM_HAL_SetClockSource(ftmBase, kClock_source_FTM_None);

    /* Set initial counter value */
    FTM_HAL_SetCounterInitVal(ftmBase, 0);
    
    /* Set MOD value */
    FTM_HAL_SetMod(ftmBase, ftmModValue);
    
    /*  Other initializations to defaults */
    FTM_HAL_SetCpwms(ftmBase, 0);
    FTM_HAL_SetDualChnCombineCmd(ftmBase, chnlPairnum, false);
    FTM_HAL_SetDualEdgeCaptureCmd(ftmBase, chnlPairnum, false);
    
    /* Configure mode to output compare, tougle output on match */
    FTM_HAL_SetChnEdgeLevel(ftmBase, clockModuleChannel, kFtmToggleOnMatch);
    FTM_HAL_SetChnMSnBAMode(ftmBase, clockModuleChannel, 1);
    
    /* Configure a match value to toggle output at */
    FTM_HAL_SetChnCountVal(ftmBase, clockModuleChannel, 1);

    /* Set clock source to start the counter */
    FTM_HAL_SetClockSource(ftmBase, kClock_source_FTM_SystemClk);
    
    /* Re-calculate the actually configured smartcard clock and return to caller */
    return (uint32_t)(((periph_clk_mhz*1000/2)/(FTM_HAL_GetMod(ftmBase)+1))*1000);
#elif defined(TPM_INSTANCE_COUNT)
    assert(clockModuleInstance < TPM_INSTANCE_COUNT);
    assert(clockModuleChannel < FSL_FEATURE_TPM_CHANNEL_COUNTn(clockModuleInstance));
    
    /* Initialize TPM driver parameter */
    tpm_pwm_param_t param = {
        kTpmCenterAlignedPWM,   /* mode */
        kTpmHighTrue,           /* edgeMode */
        cardClk,                /* uFrequencyHZ */
        50                      /* uDutyCyclePercent */
    };
    
    /* Initialize TPM driver */
    tpm_general_config_t driverInfo;
    memset(&driverInfo, 0, sizeof(driverInfo));
    
    driverInfo.isDBGMode = true;
    TPM_DRV_Init(clockModuleInstance, &driverInfo);
    
    /* Set TPM clock source, the user will have to call the Clocking API's to set the 
     * TPM module clock before calling this function */
    TPM_DRV_SetClock(clockModuleInstance, kTpmClockSourceModuleClk, kTpmDividedBy1);
    
    /* Start TPM in PWM mode to generate smart card clock */
    TPM_DRV_PwmStart(clockModuleInstance, &param, clockModuleChannel);
    
    return cardClk;
#else
    return 0;
#endif
}
/*************************************************************************
 * Function Name: FTM0_init
 * Parameters: none
 * Return: none
 * Description: FlexTimer 0 initialization
 *************************************************************************/
void FTM0_init(void)
{
  FTM_HAL_SetWriteProtectionCmd(FTM0_BASE_PTR, false);//false: Write-protection is disabled
  FTM_HAL_Enable(FTM0_BASE_PTR, true);//true: all registers including FTM-specific registers are available

  FTM_HAL_SetCounterInitVal(FTM0_BASE_PTR, (uint16_t)(-PWM_MODULO/2));
  FTM_HAL_SetMod(FTM0_BASE_PTR, (uint16_t)PWM_MODULO/2-1); // 20 kHz

  FTM_HAL_SetChnEdgeLevel(FTM0_BASE_PTR, 0, 2);
  FTM_HAL_SetChnEdgeLevel(FTM0_BASE_PTR, 1, 2);
  FTM_HAL_SetChnEdgeLevel(FTM0_BASE_PTR, 2, 2);
  FTM_HAL_SetChnEdgeLevel(FTM0_BASE_PTR, 3, 2);
  FTM_HAL_SetChnEdgeLevel(FTM0_BASE_PTR, 4, 2);
  FTM_HAL_SetChnEdgeLevel(FTM0_BASE_PTR, 5, 2);

  // output mask updated on PWM synchronization (not on rising edge of clock)
  FTM_HAL_SetMaxLoadingCmd(FTM0_BASE_PTR, true);//True to enable minimum loading point
  FTM_HAL_SetOutmaskPwmSyncModeCmd(FTM0_BASE_PTR, 1);//true if OUTMASK register is updated only by PWM sync\n

  FTM_HAL_SetDualChnPwmSyncCmd(FTM0_BASE_PTR, 0, true);//True to enable PWM synchronization
  FTM_HAL_SetDualChnPwmSyncCmd(FTM0_BASE_PTR, 1, true);
  FTM_HAL_SetDualChnPwmSyncCmd(FTM0_BASE_PTR, 2, true);
  FTM_HAL_SetDualChnDeadtimeCmd(FTM0_BASE_PTR, 0, true);//True to enable deadtime insertion, false to disable
  FTM_HAL_SetDualChnDeadtimeCmd(FTM0_BASE_PTR, 1, true);
  FTM_HAL_SetDualChnDeadtimeCmd(FTM0_BASE_PTR, 2, true);
  FTM_HAL_SetDualChnCompCmd(FTM0_BASE_PTR, 0, true);//True to enable complementary mode, false to disable
  FTM_HAL_SetDualChnCompCmd(FTM0_BASE_PTR, 1, true);
  FTM_HAL_SetDualChnCompCmd(FTM0_BASE_PTR, 2, true);
  FTM_HAL_SetDualChnCombineCmd(FTM0_BASE_PTR, 0, true);// True to enable channel pair to combine, false to disable
  FTM_HAL_SetDualChnCombineCmd(FTM0_BASE_PTR, 1, true);
  FTM_HAL_SetDualChnCombineCmd(FTM0_BASE_PTR, 2, true);

  // High transistors have negative polarity (MC33927/37)
  FTM_HAL_SetDeadtimePrescale(FTM0_BASE_PTR, kFtmDivided1);
  FTM_HAL_SetDeadtimeCount(FTM0_BASE_PTR, FTM_DEADTIME_DTVAL(63)); // DTVAL - deadtime value (0-63): deadtime period = DTPS x DTVAL
  FTM_HAL_SetInitTriggerCmd(FTM0_BASE_PTR, true);//True to enable, false to disable
  FTM_HAL_SetChnOutputPolarityCmd(FTM0_BASE_PTR, 0,  1);
  FTM_HAL_SetChnOutputPolarityCmd(FTM0_BASE_PTR, 2,  1);
  FTM_HAL_SetChnOutputPolarityCmd(FTM0_BASE_PTR, 4,  1);


  /* Following line configures:
     - enhanced PWM synchronization, FTM counter reset on SW sync
     - output SW control / polarity registers updated on PWM synchronization (not on rising edge of clock)
     - output SW control/inverting(swap)/mask registers updated from buffers on SW synchronization */  
  FTM_HAL_SetPwmSyncModeCmd(FTM0_BASE_PTR, true);// true means use Enhanced PWM synchronization\n
  FTM_HAL_SetCounterSoftwareSyncModeCmd(FTM0_BASE_PTR, true);//true means software trigger activates register sync\n
  FTM_HAL_SetSwoctrlPwmSyncModeCmd(FTM0_BASE_PTR, true);//true means SWOCTRL register is updated by PWM synch\n
  FTM_HAL_SetInvctrlPwmSyncModeCmd(FTM0_BASE_PTR, true);//true means INVCTRL register is updated by PWM synch\n
  FTM_HAL_SetSwoctrlSoftwareSyncModeCmd(FTM0_BASE_PTR, true);//true means software trigger activates register sync\n
  FTM_HAL_SetInvctrlSoftwareSyncModeCmd(FTM0_BASE_PTR, true);//true means software trigger activates register sync\n
  FTM_HAL_SetOutmaskSoftwareSyncModeCmd(FTM0_BASE_PTR, true);//true means software

  FTM_HAL_SetChnOutputMask(FTM0_BASE_PTR, 0, 1);//Sets the FTM peripheral timer channel output mask.
  FTM_HAL_SetChnOutputMask(FTM0_BASE_PTR, 1, 1);
  FTM_HAL_SetChnOutputMask(FTM0_BASE_PTR, 2, 1);
  FTM_HAL_SetChnOutputMask(FTM0_BASE_PTR, 3, 1);
  FTM_HAL_SetChnOutputMask(FTM0_BASE_PTR, 4, 1);
  FTM_HAL_SetChnOutputMask(FTM0_BASE_PTR, 5, 1);

  FTM_HAL_SetCounter(FTM0_BASE_PTR, 1U);         // update of FTM settings
  // no ISR, counting up, system clock, divide by 1
  FTM_HAL_SetClockSource(FTM0_BASE_PTR, kClock_source_FTM_SystemClk);
  
  FTM_HAL_SetChnCountVal(FTM0_BASE_PTR, 0, (uint16_t)(-PWM_MODULO/4));
  FTM_HAL_SetChnCountVal(FTM0_BASE_PTR, 1,(uint16_t) PWM_MODULO/4);
  FTM_HAL_SetChnCountVal(FTM0_BASE_PTR, 2, (uint16_t)(-PWM_MODULO/4));
  FTM_HAL_SetChnCountVal(FTM0_BASE_PTR, 3,(uint16_t) PWM_MODULO/4);
  FTM_HAL_SetChnCountVal(FTM0_BASE_PTR, 4, (uint16_t)(-PWM_MODULO/4));
  FTM_HAL_SetChnCountVal(FTM0_BASE_PTR, 5,(uint16_t) PWM_MODULO/4);

  FTM_HAL_SetSoftwareTriggerCmd(FTM0_BASE_PTR, 1);
  
  FTM_HAL_SetPwmLoadCmd(FTM0_BASE_PTR, 1);

  // FTM0 PWM output pins
  PORT_HAL_SetMuxMode(PORTC_BASE_PTR, 1, kPortMuxAlt4);
  PORT_HAL_SetMuxMode(PORTC_BASE_PTR, 3, kPortMuxAlt4);
  PORT_HAL_SetMuxMode(PORTC_BASE_PTR, 4, kPortMuxAlt4);
  PORT_HAL_SetMuxMode(PORTD_BASE_PTR, 4, kPortMuxAlt4);
  PORT_HAL_SetMuxMode(PORTD_BASE_PTR, 5, kPortMuxAlt4);
#if defined(KV10Z7_SERIES)
  PORT_HAL_SetMuxMode(PORTE_BASE_PTR, 25, kPortMuxAlt3);
#elif (defined(KV10Z1287_SERIES) || defined(KV11Z7_SERIES))
  PORT_HAL_SetMuxMode(PORTC_BASE_PTR, 2, kPortMuxAlt4);
#endif

  GPIO_HAL_SetPinDir(GPIOC_BASE_PTR, 1, kGpioDigitalOutput);
  GPIO_HAL_SetPinDir(GPIOC_BASE_PTR, 3, kGpioDigitalOutput);
  GPIO_HAL_SetPinDir(GPIOC_BASE_PTR, 4, kGpioDigitalOutput);

  GPIO_HAL_SetPinDir(GPIOD_BASE_PTR, 4, kGpioDigitalOutput);
  GPIO_HAL_SetPinDir(GPIOD_BASE_PTR, 5, kGpioDigitalOutput);
#if defined(KV10Z7_SERIES)
  GPIO_HAL_SetPinDir(GPIOE_BASE_PTR, 25, kGpioDigitalOutput);
#elif (defined(KV10Z1287_SERIES) || defined(KV11Z7_SERIES))
  GPIO_HAL_SetPinDir(GPIOC_BASE_PTR, 2, kGpioDigitalOutput);
#endif
}