FTM behaviour after reset

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

FTM behaviour after reset

1,808 Views
shaileshagrahar
Contributor III

#include <S32K144.h>

void Timer_FTM0_Init(void);
void NVIC_EnablIRQs(IRQn_Type IRQs_Number );

int main(void)
{

SystemOSC_Init();
SystemPLL_Init();
SystemRunMode_Init();
Gpio_Init();
Timer_FTM0_Init(); //! Initialization of FTM1 module
NVIC_EnablIRQs(FTM0_IRQn); //! Setting for Enabling FTM1 Interrupt and there Priorities Level
while(1)
{
}
}

 

void Timer_FTM0_Init(void)
{
//! System Clock is input to FTM counter so, no need to program
PCC->PCCn[PCC_FLEXTMR0_INDEX] = PCC_PCCn_PCS(6);
PCC->PCCn[PCC_FLEXTMR0_INDEX] |= PCC_PCCn_CGC_MASK;
FTM0->MODE |= FTM_MODE_WPDIS_MASK; //!WPDIS: Write Protection Enable for FTM register
FTM0->SC = 0;
FTM0->CNTIN = 0;
FTM0->SC = ( FTM_SC_PS(4)|FTM_SC_CLKS(1)|!FTM_SC_CPWMS_MASK
|FTM_SC_TOIE_MASK );
FTM0->MODE |= FTM_MODE_FTMEN_MASK;
FTM0->MOD = FTM_MOD_MOD(40000);
FTM0->CONTROLS[0].CnSC = (( FTM_CnSC_ELSA_MASK)|(!FTM_CnSC_ELSB_MASK)
|( FTM_CnSC_MSA_MASK)|(!FTM_CnSC_MSB_MASK));
FTM0->CONTROLS[0].CnSC |= FTM_CnSC_CHIE_MASK;
}

 

//!Handler For Flex Timer Module
void FTM0_IRQHandler (void)
{
if( FTM0->SC & FTM_SC_TOF_MASK ){
if( FTM0->STATUS & FTM_STATUS_CH0F_MASK ){
FTM0->STATUS &= !FTM_STATUS_CH0F_MASK;
Toggle_PortD(EVB_BLUE_LED);}}
}

 

void NVIC_EnablIRQs(IRQn_Type IRQs_Number )
{

 

FSL_NVIC->ICPR[1] = 1 << (IRQs_Number % 32); //! Clear any pending IRQ
FSL_NVIC->ISER[1] = 1 << (IRQs_Number % 32); //! Enable IRQ
FSL_NVIC->IP[IRQs_Number] = 9;
}

 

Hi all,
I have written the above code to generate the interrupt every millisecond . My code running good and on every second, i am getting the interrupt and so my ISR getting executed on each millisecond.
Below is description of my issue :
CASE1:
I am running my code on IAR embedded work bench:
1. After compiling my code i am using "downloading and debugging" option to flash the .elf file on IAR .
2. Now i am starting debugging the code ,with single step run .
a) First my breakpoints hit on main, as usually happens .
b) Then,It hit the Function :Timer_FTM0_Init(); (I have set the break-point on this function ).here i have initialise the FTM0_Chn0 for 1 millisecond.
c) Then it wait for 1 millisecond , this time it continue hitting the while statement till time out.
d)then as the timeout expire (40000),it execute the ISR , and toggle the LED.
Means with the option "debug and downloading " my code running smooth and as expected .

 

CASE2:
1. I have remove the all breakpoints.
2. Now, i have set the full free mode running.code running smooth on every second ISR executing and i my LED toggling .

 

My issue start from here .
3. Now i have reset the code on IAR debugger with option "reset"and then run again , now what happens :
a) First my breakpoints hit on main, as happening in First case1.
b) Then,It hit the Function :Timer_FTM0_Init(); (I have set the break-point on this function ).here i have initialise the FTM0_Chn0 for 1 millisecond.
now the issue is here ,below and skipping the step C , means it not hitting the while loop means not waiting for expiring the counting (40000) .
below step spiking not hitting here .
c) Then it wait for 1 millisecond , this time it continue hitting the while statement till time out.

 


it execute the ISR , without waiting for expiring the time out value (counting value of 40000).

 

Thanks!

Labels (1)
4 Replies

1,174 Views
PetrS
NXP TechSupport
NXP TechSupport

Hi,

Your FTM module initialization is not completely correct. Also the ISR routine is not right as you do not clear the overflow flag.

Below is the code I tested on the EVB rev1. It configured FTM0 to up counter only and set the modulo to 1 ms. Overflow interrupt is generated and PD0 pin is toggled within this ISR.

I works properly in both debug and standalone operation.

BR, Petr

// Initialize XOSC (8MHz), SPLL (160MHz) and RUN mode
void SCG_Init(void)
{
  // *** System OSC ***
  SCG->SOSCDIV=0x00000101;  /* SOSCDIV1 & SOSCDIV2 =1: divide by 1 */
  SCG->SOSCCFG=0x00000034;  /* Range=3: high freq (SOSC betw 8MHz-32MHz)*/
                            /* HGO=0:   Config xtal osc for low power */
                            /* EREFS=1: Input is external XTAL */
  while(SCG->SOSCCSR & SCG_SOSCCSR_LK_MASK); /* Ensure SOSCCSR unlocked */
  SCG->SOSCCSR=0x00000001;  /* LK=0:          SOSCCSR can be written */
                            /* SOSCCMRE=0:    OSC CLK monitor IRQ if enabled */
                            /* SOSCCM=0:      OSC CLK monitor disabled */
                            /* SOSCERCLKEN=0: Sys OSC 3V ERCLK output clk disabled */
                            /* SOSCLPEN=0:    Sys OSC disabled in VLP modes */
                            /* SOSCSTEN=0:    Sys OSC disabled in Stop modes */
                            /* SOSCEN=1:      Enable oscillator */
  while(!(SCG->SOSCCSR & SCG_SOSCCSR_SOSCVLD_MASK)); /* Wait for sys OSC clk valid */

  // *** System PLL ***
  SCG->SPLLDIV = 0x00000303;  /* SPLLDIV1 & SPLLDIV2 =3: divide by 4 */
  SCG->SPLLCFG = 0x00180000;  /* PREDIV=0: Divide SOSC_CLK by 0+1=1 */
                              /* MULT=24:  Multiply sys pll by 24+16=40 */
                              /* SPLL_CLK = 8MHz / 1 * 40 / 2 = 160 MHz */
  while(SCG->SPLLCSR & SCG_SPLLCSR_LK_MASK); /* Ensure SPLLCSR unlocked */
  SCG->SPLLCSR = 0x00000001; /* LK=0:        SPLLCSR can be written */
                             /* SPLLCMRE=0:  SPLL CLK monitor IRQ if enabled */
                             /* SPLLCM=0:    SPLL CLK monitor disabled */
                             /* SPLLSTEN=0:  SPLL disabled in Stop modes */
                             /* SPLLEN=1:    Enable SPLL */
  while(!(SCG->SPLLCSR & SCG_SPLLCSR_SPLLVLD_MASK)); /* Wait for SPLL valid */

  // *** MODE CONFIG ***
  SCG->RCCR=SCG_RCCR_SCS(6)  /* PLL as clock source*/
        |SCG_RCCR_DIVCORE(0b01)  /* DIVCORE= 2, Core/Sys clock = 80 MHz*/
        |SCG_RCCR_DIVBUS(0b11)   /* DIVBUS = 4, bus clock = 40 MHz*/
        |SCG_RCCR_DIVSLOW(0b111); /* DIVSLOW = 8, SCG slow, flash clock= 20 MHz*/

  SMC->PMCTRL  = SMC_PMCTRL_RUNM(0b00);    //enter RUN

}

void FTM0_setup(void)
{
  PCC->PCCn[PCC_FLEXTMR0_INDEX] &= 0xFFFFFFFF ^ PCC_PCCn_CGC_MASK;  /* CGC=0: Clock disabled to configure PCS */
  PCC->PCCn[PCC_FLEXTMR0_INDEX] |= PCC_PCCn_PCS(6);    /* PCS=6: SPLLDIV1_CLK = 40MHz */
  PCC->PCCn[PCC_FLEXTMR0_INDEX] |= PCC_PCCn_CGC_MASK;  /* CGC=1: Clock enabled for FTM0 */

  FTM0->MODE |= FTM_MODE_FTMEN_MASK;                   /* Enable write the FTM CnV register */
  FTM0->MOD = 40000;                                   /* 25ns * 40000 = 1ms */
  FTM0->CNTIN = 0x00;                            /* FTM counter start value */

  FTM0->SC |= FTM_SC_TOIE_MASK   | /* Enable TOF interrupts. An interrupt is generated when TOF equals one */
              FTM_SC_PS(0)       | /* PS=0: Divided by 1, and thus 40 / 1 = 40MHz */
              FTM_SC_CLKS(3);      /* CLKS=3: Use PCC_FLEXTMR0[PCS] clock (SPLLDIV1_CLK=40MHz) */
}

//!Handler For Flex Timer Module
void FTM0_IRQHandler (void)
{

    if( FTM0->SC & FTM_SC_TOF_MASK )
    {
        FTM0->SC &= 0xFFFFFFFF ^ FTM_SC_TOF_MASK;  /* Clear TOF flag */

        PTD->PTOR |= 1<<0;
    }
}
 

1,174 Views
shaileshagrahar
Contributor III

Hi petr,

Thanks again for your feedback . Actually i want to use FTM channel in my application .As we know that FTM has 8 channel .I want to work different task for one FTM module on the basis of FTM channels .

I do not to want to configure  these channel as Out put to trigger another module or device .

I want to configure these channels as timers and each channel will have a time out value , when ever the time expire for that particular channel, i want an interrupt for that channel (as CHF flag for particular channel will set ).

Means in ISR, i will perform different task , on the basis of that channel ( Set CHF flag).

i have one confusion for above  requirement , which register i will use for initial and final value .

I have modified the above code , on the basis of my understanding , please give your feed back:

in below code i am doing two work for as an example toggling BLUE and GREEN led on the basis of channel interrupt flag(CHnF).

 

void Timer_FTM0Channel_Setting(FTM0_ChannelNo_Type ChannelNo)
{
   PCC->PCCn[PCC_FLEXTMR0_INDEX] &= 0xFFFFFFFF ^ PCC_PCCn_CGC_MASK; /* CGC=0: Clock disabled to       configure PCS */
   PCC->PCCn[PCC_FLEXTMR0_INDEX] |= PCC_PCCn_PCS(6); /* PCS=6: SPLLDIV1_CLK = 40MHz */
   PCC->PCCn[PCC_FLEXTMR0_INDEX] |= PCC_PCCn_CGC_MASK; /* CGC=1: Clock enabled for FTM0 */

   FTM0->MODE |= FTM_MODE_FTMEN_MASK; /* Enable write the FTM CnV register */
   FTM0->SC |= FTM_SC_TOIE_MASK | /* Enable TOF interrupts. An interrupt is generated when TOF equals one */
   FTM_SC_PS(0) | /* PS=0: Divided by 1, and thus 40 / 1 = 40MHz */
   FTM_SC_CLKS(3);
   switch(ChannelNo)
   {
         case ChannelNo_0:
                  FTM0->CONTROLS[0].CnV = FTM_CnV_VAL(40000); /* 1 millsecond time out for Channel(0) */
                  FTM0->CNTIN = 0x00; /* FTM counter start value for Channel(0) */
                  FTM0->CONTROLS[0].CnSC = (( FTM_CnSC_ELSA_MASK) /*ELSA:Channel(0) Edge or Level Select*/
                                                                        |(!FTM_CnSC_ELSB_MASK) /*ELSB:Channel(0) Edge or Level Select*/
                                                                        |( FTM_CnSC_MSA_MASK) /*MSA:hannel(0) Mode Select */
                                                                       |(!FTM_CnSC_MSB_MASK)); /* MSB:Channel(0) Mode Select */
                 FTM0->CONTROLS[0].CnSC |= FTM_CnSC_CHIE_MASK;
                 break;
       case ChannelNo_1:
                FTM0->CONTROLS[1].CnV = FTM_CnV_VAL(20000); /* 500 micro second time out for Channel(1) */
                FTM0->CNTIN = 0x00; /* FTM counter start value for Channel(1) */
                FTM0->CONTROLS[1].CnSC = (( FTM_CnSC_ELSA_MASK)|(!FTM_CnSC_ELSB_MASK)
                                                                       |( FTM_CnSC_MSA_MASK)|(!FTM_CnSC_MSB_MASK));
               FTM0->CONTROLS[1].CnSC |= FTM_CnSC_CHIE_MASK;
               break;
      default:
               break;
     }

}


//! Exception Handler For Flex Timer Module
void FTM0_IRQHandler (void)
{

           if( FTM0->SC & FTM_SC_TOF_MASK )
            {
                        FTM0->SC &= 0xFFFFFFFF ^ FTM_SC_TOF_MASK; /* Clear TOF flag */
                        if( FTM0->STATUS & FTM_STATUS_CH0F_MASK )
                         {

                            FTM0->STATUS &= 0xFFFFFFFF ^FTM_STATUS_CH0F_MASK;
                           Toggle_PortD(EVB_BLUE_LED);
                        }
                       if( FTM0->STATUS & FTM_STATUS_CH1F_MASK )
                       {
                             FTM0->STATUS &= 0xFFFFFFFF ^FTM_STATUS_CH1F_MASK;
                            Toggle_PortD(EVB_GREEN_LED);
                       }
              }

}

Please help on this .

Thankyou!

0 Kudos

1,174 Views
PetrS
NXP TechSupport
NXP TechSupport

Hi,

This will not work for you. There is no individual counter for each FTM channel. There is single counter for FTM module and module’s channel just doing compare/capture operation with this common counter. This counter counts from CNTIN to MOD register value.

Use rather LPIT module for different periodic ISR generation.

BR, Petr

0 Kudos

1,174 Views
shaileshagrahar
Contributor III

Thank you very much .

0 Kudos