Capture rising edge

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

Capture rising edge

Jump to solution
3,337 Views
Futte
Contributor II

unsigned int irPort;

  //Port initialisering

  definePort();

  fnDebugMsg("IR\n");

  irPort = _READ_PORT_MASK(C, PORTC_BIT6);

  fnDebugDec(irPort, 0);

  //Enable the Clock to the FTM0 Module

  SIM_SCGC6 |= SIM_SCGC6_FTM0;

  FTM0_SC |= FTM_SC_PS_1; // clock prescaler / 1

  //turn off FTM write protection;

  FTM0_MODE |= FTM_MODE_WPDIS;

  FTM0_MODE |= FTM_MODE_FTMEN;

  FTM0_SC = 0x0;

  FTM0_SC = 0; //Make sure its Off!

  FTM0_CNT = 0; //Reset counter, make sure we are starting at 0

  FTM0_MOD = (FTM_CSC_ELSA | FTM_CSC_ELSB);  //Set the overflow rate

  //FTM0_MOD = IRQ_RISING_EDGE;

  FTM0_SC |= FTM_SC_TOIE; //Enable the interrupt mask.

  FTM0_SC |= FTM_SC_CLKS_SYS; //Select the System Clock

  fnDebugMsg("Timer is running, with value: ");

  //fnDebugDec(FTM0_CNT, 0);

  fnDebugDec(FTM0_MOD, 0);

0 Kudos
1 Solution
1,807 Views
adriansc
Contributor IV

Hi,

You need to configure a FTM channel to capture the rising edge. In the attachments you can find a short application using Input Capture. Have a look of it, maybe will clear your doubts.

Regards.

View solution in original post

0 Kudos
12 Replies
1,807 Views
adriansc
Contributor IV

Hi,

You can try with this configuration:

void ftm0_init(void)

{

  SIM_SCGC6 |= SIM_SCGC6_FTM0_MASK; //Enable FlexTimer 0 Clock

  FTM0_MODE = FTM_MODE_WPDIS_MASK;    //Write Protection Disable

  /*Clear FTM0 Registers*/

  FTM0_SC = 0;        

  FTM0_CNTIN = 0;     

  FTM0_CNT = 0;       

  FTM0_QDCTRL = 0;

  FTM0_COMBINE = 0;

  FTM0_C0SC = FTM_CnSC_ELSB_MASK; //Input capture on rising edge

  FTM0_OUTINIT = 0;

  FTM0_C1SC = 0;        /* Clear channel status and control register */

  FTM0_C2SC = 0;        /* Clear channel status and control register */

  FTM0_C3SC = 0;        /* Clear channel status and control register */

  FTM0_C4SC = 0;        /* Clear channel status and control register */

  FTM0_C5SC = 0;        /* Clear channel status and control register */

  FTM0_C6SC = 0;        /* Clear channel status and control register */

  FTM0_C7SC = 0;        /* Clear channel status and control register */

  FTM0_MOD = 0xFFFF; //Max frequency

  FTM0_SC = FTM_SC_TOIE_MASK | FTM_SC_CLKS(1) | FTM_SC_PS(1); //Enable interrupts

}

Maybe it will need extra configuration that depends of your application. Also this is just the FTM initialization and does not contain other modules configurations.

It is necessarily to understand how FTM in input capture mode works. Check any Kinetis familly reference manual with Flex Timer module in section Input Capture mode for FTM.

Hope this helps.

0 Kudos
1,807 Views
Futte
Contributor II

Hi

The document you are talking about, and the section, i can't find, i onpy find somethink like this http://cache.freescale.com/files/microcontrollers/doc/app_note/AN3729.pdf

What i am trying to is to calculate a pulse. O wont to put in a signal on a pin. Then go from one rising edge to the next rising edge and check the the time this take.

I have only be trying in debug

0 Kudos
1,807 Views
adriansc
Contributor IV

Hi,

Which MCU are you using?

Regards.

0 Kudos
1,807 Views
Futte
Contributor II

I am sitting with TWR-K60F120M

0 Kudos
1,807 Views
Futte
Contributor II

I have now maket some changes in the code:

void ftm0_init(void)

{

  //Enable FlexTimer 0 Clock

  POWER_UP(6, SIM_SCGC6_FTM0);

  PORTC_PCR6 |= PORT_MUX_ALT3;

  // FLEX Timer1 configuration   

  FTM0_SC = FTM_SC_PS_16;    // TOF=0 TOIE=0 CPWMS=0 CLKS=01 (system clock)  (divide by 16)   

  // modulo to max

  FTM0_MOD = 0xffff;   

  // CHF=0 CHIE=1 MSB=0 MSA=0 ELSB=0 ELSA=1 DMA=0

  FTM0_C0SC = FTM_CSC_CHIE; 

  FTM0_C0SC = FTM_CSC_ELSA;

  //Enable the counter to run in the BDM mode

  FTM0_CONF |= FTM_CONF_BDMMODE_3;

  fnDebugDec(FTM0_C0SC, 0);

  fnEnterInterrupt(irq_FTM0_ID, PRIORITY_EMAC, FlexTimer0_Irq);

}

void FlexTimer0_Irq()

and when i debug i can see i am going in and starting the timer, i think my problem is with the mux, where i not goth it connected with my ir input (PORTC pin6) and i newer read my input :smileysad:

0 Kudos
1,808 Views
adriansc
Contributor IV

Hi,

You need to configure a FTM channel to capture the rising edge. In the attachments you can find a short application using Input Capture. Have a look of it, maybe will clear your doubts.

Regards.

0 Kudos
1,807 Views
Futte
Contributor II

Maybe it is my understanding off the timer tehr eis bad, but i cant geth any value in to the timer, and geth the value out :smileysad:

0 Kudos
1,807 Views
Futte
Contributor II

Hi Adrian

i have now tryet to make som changes and so on, I am for the shcool sitting and working i uTasker and using Codewarrior.

I have maket this code now

volatile unsigned char startPulse = 0;

extern void ftm1_isr(void)
{
unsigned char pulseWidth = 0;
unsigned char stopPulse = FTM1_C0V;

//Clear channel interrupt flag(CHF)
FTM1_C0SC &= ~0x80;

pulseWidth = stopPulse - startPulse;

if(pulseWidth> 1)
{
  fnDebugDec(pulseWidth++, 0);
 
}
}


void setupFTM1()
{
SIM_SCGC6 |= SIM_SCGC6_FTM1; /* Enable clock for FTM2 */
//Flex timer1 input filter configuration
FTM1_FILTER = 0x07;

//Flex timer configuration
FTM1_SC = 0x0C; // TOF=0 TOIE=0 CPWMS=0 CLKS=01 (system clock) PS=100 (divide by 16)
FTM1_MOD = 0xFFFF;// modulo to max
FTM1_C0SC = 0x44;  // CHF=0 CHIE=1 MSB=0 MSA=0 ELSB=0 ELSA=1 DMA=0

//Interrupt-
fnEnterInterrupt(irq_FTM0_ID, PRIORITY_EMAC, ftm1_isr);
 
PORTC_PCR6|= (0|PORT_ISF|PORT_MUX_ALT4);



}


extern void fnMyTestTask(TTASKTABLE *ptrTaskTable)
{
SIM_SCGC5 |= (SIM_SCGC5_PORTA |
         SIM_SCGC5_PORTB |
         SIM_SCGC5_PORTC |
         SIM_SCGC5_PORTD |
         SIM_SCGC5_PORTE);
setupFTM1();
}

I have tryet to debug the code and i am starting the timer. The problem is when i enter PORTC_PCR6|= (0|PORT_ISF|PORT_MUX_ALT4); my problem is comming, i am not getting anything in.

I have tryet the most of the day to geth

INT_FTM0-16);

to work but woth i now is this teh same:  fnEnterInterrupt(irq_FTM0_ID, PRIORITY_EMAC, ftm1_isr);

I have tryet to make a projekt with a simple LED and leth that blink when i detecht the Ir and thats working fine :smileyhappy:

It is still something with my compare there getting wrong or only the mux?

0 Kudos
1,807 Views
Futte
Contributor II

Hi i have be fighting with the file you send me and tryit to put my program up like that and make a capture on the PCRC_BIT6 but i am not getthing anything. i have have tryit to to add a simple check in the isr

FMT1_CNT = 0; - reset counter

FMT1_CnSC.CHF = 0;

if(FMT1_SC.TOF)

{

    ----invalid value, try again...

}

else

{

    short FtmResult = CnV.VAL; // that is your valid result.

}

but i newer geth anything out :smileysad:

are you having a idea what its cant be wrong, am i needed to put in a signal on to pins ? i only have one signal.

//Mick

0 Kudos
1,807 Views
Filippo
Contributor III

Maybe this can help you.

Remember to set the correct vector in your interrupt table.

File main.c

/*

* This application implements Input Capture mode for FTM0 with interrupt

* Autor: Graziano Pagani

* Partially stolen from Mr. Adrian Sanchez Cano's code

* Novasis

*/

#include "derivative.h" /* include peripheral declarations */

#include "main.h"

/* tower module LED defines */

#define LED0_EN (PORTA_PCR11 = PORT_PCR_MUX(1))

#define LED0_TOGGLE (GPIOA_PTOR = (1<<11))

#define LED0_OFF (GPIOA_PSOR = (1<<11))

#define LED0_ON (GPIOA_PCOR = (1<<11))

 

int count = 0;

int main(void)

{

int counter = 0;

    SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK | SIM_SCGC5_PORTB_MASK | SIM_SCGC5_PORTC_MASK | SIM_SCGC5_PORTD_MASK | SIM_SCGC5_PORTE_MASK;

    GPIOA_PDDR |= (1<<11);

    LED0_EN;

    LED0_ON;

    ftm0_init();

    nvic_init();

    for(;;)

    {

           counter++;

    }

    return 0;

}

void ftm0_init(void)

{

    //Enable FlexTimer 0 Clock

    SIM_SCGC6 |= SIM_SCGC6_FTM0_MASK; /* Enable clock for FTM2 */

    PORTC_PCR3|= (0|PORT_PCR_ISF_MASK|PORT_PCR_MUX(4)); 

    // FTM0_CH2

    FTM0_MODE |= FTM_MODE_WPDIS_MASK;

    FTM0_CNT = 0;                    //reset the counter to zero

    FTM0_MOD = 0xffff ;              //Set the overflow rate

    FTM0_CNTIN = 0;                 //Set the Counter Initial Value to 0

    FTM0_MODE |= FTM_MODE_FTMEN_MASK;

    // FLEX Timer0 configuration

    FTM0_SC |= (FTM_SC_PS(0)| FTM_SC_CLKS(1));   

    // TOF=0 TOIE=0 CPWMS=0 CLKS=01 (system clock)  (divide by 1)  

    FTM0_C1SC = 0;        /* Clear channel status and control register */

    FTM0_C2SC = 0;        /* Clear channel status and control register */

    FTM0_C3SC = 0;        /* Clear channel status and control register */

    FTM0_C4SC = 0;        /* Clear channel status and control register */

    FTM0_C5SC = 0;        /* Clear channel status and control register */

    FTM0_C6SC = 0;        /* Clear channel status and control register */

    FTM0_C7SC = 0;        /* Clear channel status and control register */

   

     FTM0_C2SC |= (0|FTM_CnSC_ELSA_MASK | FTM_CnSC_CHIE_MASK);

     FTM0_MODE |= FTM_MODE_FTMEN_MASK;

     FTM0_COMBINE = 0;

     FTM0_QDCTRL = 0;

    

     //Enable the counter to run in the BDM mode

     FTM0_CONF |= FTM_CONF_BDMMODE(0); 

}

void FTM0_isr(void)

{

int event = 0;

int overflow = 0;

int status = 0;

    LED0_TOGGLE; //Toggle LED

    status = FTM0_SC;

    if (FTM0_C2SC & FTM_CnSC_CHF_MASK)

    {

        FTM0_C2SC &= ~FTM_CnSC_CHF_MASK;

        event = 1;

        count = FTM0_C2V & FTM_CnV_VAL_MASK;

        FTM0_CNT = 0;                    //reset the counter to zero

    }

        

    if (FTM0_SC & FTM_SC_TOF_MASK)

    {

        FTM0_SC &= ~FTM_SC_TOF_MASK;

        overflow = 1;

    }

}

void nvic_init (void)

{

    EnableInterrupts;

    enable_irq(INT_FTM0-16);

}

void enable_irq (int irq)

{

    int div;

/* Determine which of the NVICISERs corresponds to the irq */

    div = irq/32;

    switch (div)

    {

        case 0x0:

            NVICICPR0 |= 1 << (irq%32);

            NVICISER0 |= 1 << (irq%32);

            break;

        case 0x1:

            NVICICPR1 |= 1 << (irq%32);

            NVICISER1 |= 1 << (irq%32);

            break;

        case 0x2:

            NVICICPR2 |= 1 << (irq%32);

            NVICISER2 |= 1 << (irq%32);

            break;

       }

}

File main.h

/*

* This application implements Input Capture mode for FTM0 with interrupt

* Autor: Graziano Pagani

* Partially stolen from Mr. Adrian Sanchez Cano's code

* Novasis

*/

#ifndef MAIN_H_

#define MAIN_H_

#define EnableInterrupts asm(" CPSIE i");

void FTM0_isr(void);

void ftm0_init(void);

void enable_irq (int irq);

void set_irq_priority (int irq, int prio);

void nvic_init (void);

#endif /* MAIN_H_ */

0 Kudos
1,807 Views
adriansc
Contributor IV

Hi Futte,

Do you have any questions about your configurations?

Regards.

0 Kudos
1,807 Views
Futte
Contributor II

Yes i have some problems with capturing rising edge and write it out to me, i think i have some problems understanding the flextimer, howe can i geth the value, and leth it start by a signal ?

0 Kudos