/*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); }
/*! * @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; } }
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 */ } }
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 */ } }