/*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); }
/*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); }
/* --------------------------------------- */ static void StartStopFTM(uint32_t instance, bool startIt) { FTM_Type *ftmBase = g_ftmBase[instance]; if (startIt) { FTM_HAL_SetClockSource(ftmBase, kClock_source_FTM_SystemClk); /* clock timer */ } else { FTM_HAL_SetClockSource(ftmBase, kClock_source_FTM_None); /* disable clock */ } }
/*FUNCTION********************************************************************** * * Function Name : FTM_DRV_QuadDecodeStop * Description : De-activates quadrature decode mode. * This function will initialize the Real Time Clock module. * *END**************************************************************************/ void FTM_DRV_QuadDecodeStop(uint32_t instance) { /* Stop the FTM counter */ FTM_HAL_SetClockSource(g_ftmBase[instance], kClock_source_FTM_None); FTM_HAL_SetQuadDecoderCmd(g_ftmBase[instance], false); }
/*FUNCTION********************************************************************** * * Function Name : FTM_DRV_QuadDecodeStart * Description : Configures the parameters needed and activates quadrature * decode mode. * *END**************************************************************************/ void FTM_DRV_QuadDecodeStart(uint32_t instance, ftm_phase_params_t *phaseAParams, ftm_phase_params_t *phaseBParams, ftm_quad_decode_mode_t quadMode) { assert(instance < FTM_INSTANCE_COUNT); assert(phaseAParams); assert(phaseBParams); FTM_Type *ftmBase = g_ftmBase[instance]; FTM_HAL_SetQuadMode(ftmBase, quadMode); FTM_HAL_SetQuadPhaseAFilterCmd(ftmBase, phaseAParams->kFtmPhaseInputFilter); if (phaseAParams->kFtmPhaseInputFilter) { /* Set Phase A filter value if phase filter is enabled */ FTM_HAL_SetChnInputCaptureFilter(ftmBase, CHAN0_IDX, phaseAParams->kFtmPhaseFilterVal); } FTM_HAL_SetQuadPhaseBFilterCmd(ftmBase, phaseBParams->kFtmPhaseInputFilter); if (phaseBParams->kFtmPhaseInputFilter) { /* Set Phase B filter value if phase filter is enabled */ FTM_HAL_SetChnInputCaptureFilter(ftmBase, CHAN1_IDX, phaseBParams->kFtmPhaseFilterVal); } FTM_HAL_SetQuadPhaseAPolarity(ftmBase, phaseAParams->kFtmPhasePolarity); FTM_HAL_SetQuadPhaseBPolarity(ftmBase, phaseBParams->kFtmPhasePolarity); FTM_HAL_SetQuadDecoderCmd(ftmBase, true); /* Set clock source to start the counter */ FTM_HAL_SetClockSource(ftmBase, s_ftmClockSource); }
void FTM_DRV_QuadDecodeStart(uint8_t instance, ftm_phase_params_t *phaseAParams, ftm_phase_params_t *phaseBParams, ftm_quad_decode_mode_t quadMode) { assert(instance < HW_FTM_INSTANCE_COUNT); assert(phaseAParams); assert(phaseBParams); uint32_t ftmBaseAddr = g_ftmBaseAddr[instance]; FTM_HAL_SetQuadMode(ftmBaseAddr, quadMode); FTM_HAL_SetQuadPhaseAFilterCmd(ftmBaseAddr, phaseAParams->kFtmPhaseInputFilter); if (phaseAParams->kFtmPhaseInputFilter) { /* Set Phase A filter value if phase filter is enabled */ FTM_HAL_SetChnInputCaptureFilter(ftmBaseAddr, HW_CHAN0, phaseAParams->kFtmPhaseFilterVal); } FTM_HAL_SetQuadPhaseBFilterCmd(ftmBaseAddr, phaseBParams->kFtmPhaseInputFilter); if (phaseBParams->kFtmPhaseInputFilter) { /* Set Phase B filter value if phase filter is enabled */ FTM_HAL_SetChnInputCaptureFilter(ftmBaseAddr, HW_CHAN1, phaseBParams->kFtmPhaseFilterVal); } FTM_HAL_SetQuadPhaseAPolarity(ftmBaseAddr, phaseAParams->kFtmPhasePolarity); FTM_HAL_SetQuadPhaseBPolarity(ftmBaseAddr, phaseBParams->kFtmPhasePolarity); FTM_HAL_SetQuadDecoderCmd(ftmBaseAddr, true); /* Set clock source to start the counter */ FTM_HAL_SetClockSource(ftmBaseAddr, kClock_source_FTM_SystemClk); }
/*FUNCTION********************************************************************** * * Function Name : FTM_DRV_CounterStop * Description : Stops the FTM counter. * *END**************************************************************************/ void FTM_DRV_CounterStop(uint32_t instance) { /* Stop the FTM counter */ FTM_HAL_SetClockSource(g_ftmBase[instance], kClock_source_FTM_None); FTM_HAL_SetCpwms(g_ftmBase[instance], 0); /* Disable the overflow interrupt */ FTM_DRV_SetTimeOverflowIntCmd(instance, false); }
/************************************************************************* * Function Name: FTM2_init * Parameters: none * Return: none * Description: FlexTimer 2 initialization *************************************************************************/ void FTM2_init(void) { FTM_HAL_SetWriteProtectionCmd(FTM2_BASE_PTR, false);//false: Write-protection is disabled FTM_HAL_Enable(FTM2_BASE_PTR, true);//true: all registers including FTM-specific registers are available FTM_HAL_SetMod(FTM2_BASE_PTR, (uint16_t)0xffff);// Free running timer FTM_HAL_SetClockSource(FTM2_BASE_PTR, kClock_source_FTM_SystemClk);//clock The FTM peripheral clock selection\n FTM_HAL_SetClockPs(FTM2_BASE_PTR, kFtmDividedBy2); // system clock, divide by 2 FTM_HAL_EnableChnInt(FTM2_BASE_PTR, 0);//Enables the FTM peripheral timer channel(n) interrupt. FTM_HAL_SetChnMSnBAMode(FTM2_BASE_PTR, 0, 1);//Sets the FTM peripheral timer channel mode. INT_SYS_EnableIRQ(FTM2_IRQn); set_irq_priority(FTM2_IRQn, ISR_PRIORITY_SLOW_TIMER); }
/*FUNCTION********************************************************************** * * Function Name : FTM_DRV_PwmStop * Description : Stops channel PWM. * *END**************************************************************************/ void FTM_DRV_PwmStop(uint32_t instance, ftm_pwm_param_t *param, uint8_t channel) { assert((param->mode == kFtmEdgeAlignedPWM) || (param->mode == kFtmCenterAlignedPWM) || (param->mode == kFtmCombinedPWM)); assert(instance < FTM_INSTANCE_COUNT); assert(channel < g_ftmChannelCount[instance]); FTM_Type *ftmBase = g_ftmBase[instance]; /* Stop the FTM counter */ FTM_HAL_SetClockSource(ftmBase, kClock_source_FTM_None); FTM_HAL_DisablePwmMode(ftmBase, param, channel); /* Clear out the registers */ FTM_HAL_SetMod(ftmBase, 0); FTM_HAL_SetCounter(ftmBase, 0); }
/*See fsl_ftm_driver.h for documentation of this function.*/ void FTM_DRV_PwmStop(uint8_t instance, ftm_pwm_param_t *param, uint8_t channel) { assert((param->mode == kFtmEdgeAlignedPWM) || (param->mode == kFtmCenterAlignedPWM) || (param->mode == kFtmCombinedPWM)); assert(instance < HW_FTM_INSTANCE_COUNT); assert(channel < FSL_FEATURE_FTM_CHANNEL_COUNTn(instance)); uint32_t ftmBaseAddr = g_ftmBaseAddr[instance]; /* Stop the FTM counter */ FTM_HAL_SetClockSource(ftmBaseAddr, kClock_source_FTM_None); FTM_HAL_DisablePwmMode(ftmBaseAddr, param, channel); /* Clear out the registers */ FTM_HAL_SetMod(ftmBaseAddr, 0); FTM_HAL_SetCounter(ftmBaseAddr, 0); }
/*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 : 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; }
/************************************************************************* * 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 }
/*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); }
/*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, ¶m, clockModuleChannel); return cardClk; #else return 0; #endif }
/*! * @brief Main demo function. */ int main (void) { ftm_pwm_param_t xAxisParams, yAxisParams; accel_dev_t accDev; accel_dev_interface_t accDevice; accel_sensor_data_t accelData; accel_i2c_interface_t i2cInterface; int16_t xData, yData; int16_t xAngle, yAngle; uint32_t ftmModulo; // Register callback func for I2C i2cInterface.i2c_init = I2C_DRV_MasterInit; i2cInterface.i2c_read = I2C_DRV_MasterReceiveDataBlocking; i2cInterface.i2c_write = I2C_DRV_MasterSendDataBlocking; accDev.i2c = &i2cInterface; accDev.accel = &accDevice; accDev.slave.baudRate_kbps = BOARD_ACCEL_BAUDRATE; accDev.slave.address = BOARD_ACCEL_ADDR; accDev.bus = BOARD_ACCEL_I2C_INSTANCE; // Initialize standard SDK demo application pins. hardware_init(); // Accel device driver utilizes the OSA, so initialize it. OSA_Init(); // Initialize the LEDs used by this application. LED2_EN; LED3_EN; // Print the initial banner. PRINTF("Bubble Level Demo!\r\n\r\n"); // Initialize the Accel. accel_init(&accDev); // Turn on the clock to the FTM. CLOCK_SYS_EnableFtmClock(BOARD_FTM_INSTANCE); // Initialize the FTM module. FTM_HAL_Init(BOARD_FTM_BASE); // Configure the sync mode to software. FTM_HAL_SetSyncMode(BOARD_FTM_BASE, kFtmUseSoftwareTrig); // Enable the overflow interrupt. FTM_HAL_EnableTimerOverflowInt(BOARD_FTM_BASE); // Set the FTM clock divider to /16. FTM_HAL_SetClockPs(BOARD_FTM_BASE, kFtmDividedBy16); // Configure the FTM channel used for the X-axis. Initial duty cycle is 0%. xAxisParams.mode = kFtmEdgeAlignedPWM; xAxisParams.edgeMode = kFtmHighTrue; FTM_HAL_EnablePwmMode(BOARD_FTM_BASE, &xAxisParams, BOARD_FTM_X_CHANNEL); FTM_HAL_SetChnCountVal(BOARD_FTM_BASE, BOARD_FTM_X_CHANNEL, 0); // Configure the FTM channel used for the Y-axis. Initial duty cycle is 0%. yAxisParams.mode = kFtmEdgeAlignedPWM; yAxisParams.edgeMode = kFtmHighTrue; FTM_HAL_EnablePwmMode(BOARD_FTM_BASE, &yAxisParams, BOARD_FTM_Y_CHANNEL); FTM_HAL_SetChnCountVal(BOARD_FTM_BASE, BOARD_FTM_Y_CHANNEL, 0); // Get the FTM reference clock and calculate the modulo value. ftmModulo = (CLOCK_SYS_GetFtmSystemClockFreq(BOARD_FTM_INSTANCE) / (1 << FTM_HAL_GetClockPs(BOARD_FTM_BASE))) / (BOARD_FTM_PERIOD_HZ - 1); // Initialize the FTM counter. FTM_HAL_SetCounterInitVal(BOARD_FTM_BASE, 0); FTM_HAL_SetMod(BOARD_FTM_BASE, ftmModulo); // Set the clock source to start the FTM. FTM_HAL_SetClockSource(BOARD_FTM_BASE, kClock_source_FTM_SystemClk); // Enable the FTM interrupt at the NVIC level. INT_SYS_EnableIRQ(BOARD_FTM_IRQ_VECTOR); // Main loop. Get sensor data and update globals for the FTM timer update. while(1) { // Wait 5 ms in between samples (accelerometer updates at 200Hz). OSA_TimeDelay(5); // Get new accelerometer data. accDev.accel->accel_read_sensor_data(&accDev,&accelData); // Turn off interrupts (FTM) while updating new duty cycle values. INT_SYS_DisableIRQGlobal(); // Get the X and Y data from the sensor data structure. xData = (int16_t)((accelData.data.accelXMSB << 8) | accelData.data.accelXLSB); yData = (int16_t)((accelData.data.accelYMSB << 8) | accelData.data.accelYLSB); // Convert raw data to angle (normalize to 0-90 degrees). No negative // angles. xAngle = abs((int16_t)(xData * 0.011)); yAngle = abs((int16_t)(yData * 0.011)); // Set values for next FTM ISR udpate. Use 5 degrees as the threshold // for whether to turn the LED on or not. g_xValue = (xAngle > 5) ? (uint16_t)((xAngle / 90.0) * ftmModulo) : 0; g_yValue = (yAngle > 5) ? (uint16_t)((yAngle / 90.0) * ftmModulo) : 0; // Re-enable interrupts. INT_SYS_EnableIRQGlobal(); // Print out the raw accelerometer data. PRINTF("x= %d y = %d\r\n", xData, yData); } }