/*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);
}
Пример #2
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;
    }
}
Пример #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 */
  }
}
Пример #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 */
  }
}