AnsweredAssumed Answered

FTM for variable pulse widths

Question asked by James Millard on Jun 20, 2019
Latest reply on Jul 16, 2019 by James Millard

I am trying to get the FTM module to allow me to create a chain of pulses on a GPIO with varying widths -- all with 50% duty cycle and then turn the FTM module off at the end of the train of pulses.  I thought I could change the MOD and CnV values in the interrupt, but it doesn't seem to work.  Here is the FTM configuration:

ftm_data.data = 0xAAAA;
ftm_data.mask = 0x8000;

// Turn on
SIM_SCGC3 |= SIM_SCGC3_FTM3_MASK;
PORTD_PCR3 = PORT_PCR_MUX(GPIO_PCR_MUX_ALT4) | PORT_PCR_DSE_MASK;

FTM3_MODE |= FTM_MODE_WPDIS_MASK;
FTM3_SC = 0x0;
FTM3_CONF = 0x0;
FTM3_CNT = 0x0;
FTM3_C3SC = FTM_CnSC_MSA(0x1) | FTM_CnSC_ELSA(1) | FTM_CnSC_ELSB(0);
FTM3_MOD = FTM_PERIOD_START;
FTM3_C3V = FTM3_MOD/2;
FTM3_SC = FTM_SC_CLKS(0x1) | FTM_SC_PS(0x0) | FTM_SC_TOIE_MASK;

enable_irq(FTM3_IRQn);

Here is the interrupt:

void FTM3_IRQHandler(void)
{
   if (FTM3_SC & FTM_SC_TOF_MASK)
   {
      FTM3_SC &= ~FTM_SC_TOF_MASK;
      if (ftm_data.mask)
      {
         FTM3_MOD = ftm_data.data & ftm_data.mask ? FTM_PERIOD_LOGICAL_ZERO : FTM_PERIOD_LOGICAL_ONE;
         FTM3_C3V = FTM3_MOD/2;
         FTM3_PWMLOAD |= FTM_PWMLOAD_LDOK_MASK;

         ftm_data.mask >>= 1;
      }
      else
      {
         FTM3_SC = 0x0;
      }
   }
}

The idea was to have an initial pulse period defined by FTM_PERIOD_START in the first code snippet.  Then in the interrupt set a long or short pulse depending on the data set in ftm_data.data and'd with ftm_data.mask.  The pulse widths I need are anywhere from 6 us to 40 us.  

 

ftm_data is a global structure with two members, data and mask.

 

Am I going about this the wrong way?  What I get is 9 pulses (should be 17).  Also, the duty cycle of the first pulse varies and the successive pulses all appear have either a 0 or 100% duty cycle.  Not sure what to do at this point.

 

I'm using the K64 Freedom Board and KDS 3.0, if it matters.

 

Thanks.

Outcomes