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?
解決済! 解決策の投稿を見る。
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.
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.
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?
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.
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.
You might also get some benefit from my working implementation, complete with Index capture, in:
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.