quadrature decoder / FTM how-to

cancel
Showing results for 
Search instead for 
Did you mean: 

quadrature decoder / FTM how-to

Jump to solution
3,316 Views
stderr
Contributor II

I'm attempting to enable the quadrature decoder in a K10 series part. I have an encoder connected to inputs PHA/B or PTA10 & 11, corresponding to FTM2. Reading the manual, in order to enable this, I need to set FTMEN and QUADEN.  Here's what I did:

FTM2_MODE = 0x00000005;          // WRTDIS bit is already set, default after reset.

FTM2_SC = 0x00000028;

FTM2_QDCTRL = 0x00000001;

FTM2_CNT = 100;          // manual says write to this before writing to FTM2_CNTIN

FTM2_CNTIN = 0;

FTM2_MOD = 0x00007fff;

The WRTEN bit is set, and the WRTDIS bit is clear.

The filters are off, and should be disabled, and the clock is enabled to the FTM.

If I turn the encoder, I can see the PHA/B inputs changing on the pins, checked with a scope.

The FTM2_MOD register never reflects the write of 0x00007ffff to it & I never get anything other than 0 in the FTM2_CNT register.

I've read and reread the section of the manual on quadrature decoder mode, and I can't see anything in the block diagram or anywhere else that I'm not putting into the required state. I have also tried the same configuration with FTM1, and got the same results. What am I missing?

1 Solution
1,136 Views
adriansc
Contributor IV

Hi,

Write something to FTMx_CNT resets the counter to CNTIN value. Try the configuration that is on the AN:

//enable the clock for FTM1

SIM_SCGC6 |= SIM_SCGC6_FTM1_MASK;

//enable the counter

FTM1_MODE |= FTM_MODE_FTMEN_MASK;

//enable the counter to run in the BDM mode

FTM1_CONF |= FTM_CONF_BDMMODE(3);

//load the Modulo register and counter initial value

FTM1_MOD = 4095;

FTM1_CNTIN = 0;

//configuring FTM for quadrature mode

FTM1_QDCTRL |= FTM_QDCTRL_QUADEN_MASK; <---------------(Note)

// start the timer clock, source is the external clock

FTM1_SC |= FTM_SC_CLKS(3); <--------------------------------------(Note)

//configuring the input pins:

PORTA_PCR8 = PORT_PCR_MUX(6); // FTM1 CH0

PORTA_PCR9 = PORT_PCR_MUX(6); // FTM1 CH1

Note:

There is something important here, QUADEN field selects quadrature mode for FTM and has to be written before FTM configuration. Also FTM1_SC[CLKS] needs to be 0 during the configuration in order to apply changes, after that you need to select a Clock Source.

Hope this helps.

View solution in original post

0 Kudos
6 Replies
1,136 Views
adriansc
Contributor IV

Hi,

Have a look at this  application note, it could be helpful in your project.

"Configuring the FlexTimer for Position and Speed Measurement with an Encoder" (AN4381)

http://cache.freescale.com/files/32bit/doc/app_note/AN4381.pdf?fsrch=1&sr=3

Hope this helps.

1,136 Views
stderr
Contributor II

Thanks for the suggestions. I found that if I write something other than 0 to the CNTIN register  I can count from  whatever I write up to 0 before the counter stops counting, & counting works in both directions. If I look at the FTM2_MOD register in codewarrior, it's always 0, no matter what I write to it. Not only that, but the FTM_CNT register doesn't appear to be writable either. It comes up with a count (consistently) but it's not what I wrote, ever. Are these registers locked, or only writable at certain times? Is FTM2_MOD not readable? Do I need to write something somewhere else first in order to make it work?

0 Kudos
1,137 Views
adriansc
Contributor IV

Hi,

Write something to FTMx_CNT resets the counter to CNTIN value. Try the configuration that is on the AN:

//enable the clock for FTM1

SIM_SCGC6 |= SIM_SCGC6_FTM1_MASK;

//enable the counter

FTM1_MODE |= FTM_MODE_FTMEN_MASK;

//enable the counter to run in the BDM mode

FTM1_CONF |= FTM_CONF_BDMMODE(3);

//load the Modulo register and counter initial value

FTM1_MOD = 4095;

FTM1_CNTIN = 0;

//configuring FTM for quadrature mode

FTM1_QDCTRL |= FTM_QDCTRL_QUADEN_MASK; <---------------(Note)

// start the timer clock, source is the external clock

FTM1_SC |= FTM_SC_CLKS(3); <--------------------------------------(Note)

//configuring the input pins:

PORTA_PCR8 = PORT_PCR_MUX(6); // FTM1 CH0

PORTA_PCR9 = PORT_PCR_MUX(6); // FTM1 CH1

Note:

There is something important here, QUADEN field selects quadrature mode for FTM and has to be written before FTM configuration. Also FTM1_SC[CLKS] needs to be 0 during the configuration in order to apply changes, after that you need to select a Clock Source.

Hope this helps.

0 Kudos
1,136 Views
stderr
Contributor II

Thank-you Adrian!

That you can't write FTMx_MOD and FTMx_CNTIN while the clock is enabled into the quadrature decoder is the piece of information I didn't understand.

Not sure about the philosophy behind such a restriction, but so long as I can make it do what I need, so be it.

0 Kudos
1,136 Views
egoodii
Senior Contributor III

You might also get some benefit from my working implementation, complete with Index capture, in:

QEI inputs, and index capture

0 Kudos
1,136 Views
paulmartin
Contributor III

Your code seems ok to me. Only thing i can imagine is that the order of register writes could be important. Some of the registers like MOD have "write buffers" that only take effect later.

When I tested quadrature encoder mode the following code worked for me:

It is counting pulses on Phase A with the abbility to count up or down according to Phase B

// Flextimer 1 Setup / Quadrature Decoder Mode for counting pulses

SIM->SCGC6    |= (1UL <<  25);/* Enable FTM1 Clock          */

  SIM->SCGC5    |= (1UL <<  10);/* Enable Port B Clock        */

PORTB->PCR[0]  = 0x00000600;  /* setup pin for FTM1 PHA     */

PORTB->PCR[0]  = 0x00000600;  /* setup pin for FTM1 PHB     */

FTM1->MODE = 0x00000005;   /* enable advanced FTM registers */

FTM1->CNTIN = 0x00000000;   /* initial counter value after overflow */

FTM1->CNT = 0x00000000;    /* current count, writing reloads CNTIN */

FTM1->MOD = 0x0000FFFF;    /* overflow count -> free running counter */

FTM1->SC = 0x00000048;    /* FTM clock = 48MHz / 8 = 6.0 MHz, TOF interrupt enabled */

FTM1->FILTER = 0x000000044;  /* input filter on PHA and PHB, adjusted for counting up to 1MHz signals */

FTM1->QDCTRL = 0x000000D9;  /* quadrature decoder ensabled*/

NVIC_EnableIRQ(FTM1_IRQn);    /* Enable FTM1 Interrupt      */

So try changing the order of your register writes. Hope this helps.

0 Kudos