LS1021a FTM Quadrature Decoder Filtering

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

LS1021a FTM Quadrature Decoder Filtering

1,393 Views
martinhundebøll
Contributor II

We have implemented a Linux driver for the FTM Quadrature Decoder on an LS1021a based platform. The decoder works, but we are unable to enable the channel filtering for PHA and PHB. Our setup consists of the following register writes:

/* working setup without filtering */
ftm_write(ftm_base, FTM_MODE, FTM_MODE_WPDIS | /* disable write protect */
                              FTM_MODE_FTMEN); /* enable FTM */
ftm_write(ftm_base, FTM_CNTIN, 0x0);           /* zero init value */
ftm_write(ftm_base, FTM_MOD, 0xffff);          /* max overflow value */
ftm_write(ftm_base, FTM_CNT, 0x0);             /* set counter value */
ftm_write(ftm_base, FTM_SC, FTM_SC_PS_1);      /* prescale with x1 */
ftm_write(ftm_base, FTM_QDCTRL, FTM_QDCTRL_QUADEN); /* select quad mode */‍‍‍‍‍‍‍
ftm_write(ftm_base, FTM_MODE, FTM_MODE_FTMEN); /* enable FTM (enable WP) */‍‍‍‍‍‍‍‍‍

According to the reference manual, filtering is enabled by configuring the filter values in FTM_FILTER, and set the two enable bits in FTM_QDCTRL:

/* Filter enable bits in FTM_QDCTRL aren't updated */
ftm_write(ftm_base, FTM_MODE, FTM_MODE_WPDIS | /* disable write protect */
                              FTM_MODE_FTMEN); /* enable FTM */
ftm_write(ftm_base, FTM_CNTIN, 0x0);           /* zero init value */
ftm_write(ftm_base, FTM_MOD, 0xffff);          /* max overflow value */
ftm_write(ftm_base, FTM_CNT, 0x0);             /* set counter value */
ftm_write(ftm_base, FTM_SC, FTM_SC_PS_1);      /* prescale with x1 */
ftm_write(ftm_base, FTM_FILTER, 0xff);         /* max filter on PHA and PHB */

/* this write seems to have no effect on the two filter bits? */
ftm_write(ftm_base, FTM_QDCTRL, FTM_QDCTRL_QUADEN |    /* select quad mode */
                                FTM_QDCTRL_PHAFLTREN | /* enable PHA filter */
                                FTM_QDCTRL_PHBFLTREN); /* enable PHB filter */

ftm_write(ftm_base, FTM_MODE, FTM_MODE_FTMEN); /* enable FTM (enable WP) */‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

When reading back the FTM_QDCTRL register only bit zero is set (FTM_QDCTRL_QUADEN), and the rest is zero. We have tried setting other bits in the same register (i.e. FTM_QDCTRL_PHAPOL and FTM_QDCTRL_PHBPOL), which works fine.

I have tried initializing the same registers on the LS1021a-twr evaluation board running the freescale BSP with the same results.

Is there some inter-register dependency for PHAFLTREN and PHAFLTREN that we have missed?

Thanks,

Martin

Labels (1)
5 Replies

944 Views
kjeldflarup
Contributor II

After a longer discussion with NXP support we got this answer:

Looks like this is going to be a chip errata. The PHAFLTREN and PHBFLTREN bits are tide to zero internally and these bits can not be set.
Flextimer cannot use Filter in Quadrature Decoder Mode.

944 Views
kjeldflarup
Contributor II

I have been following up on this problem, and nothing seems to change the values of PHAFLTREN and PHBFLTREN, below is how my initialization of the FTM module is done in the kernel driver at boot time. I verify the settings of the FTM_SC registers and the FTM_FILTER to this:

ftm-quaddec QDCTRL register: PHAFLTREN=0 PHBFLTREN=0 PHAPOL=0 PHBPOL=0 QUADMODE=0 QUADDIR=0 TOFDIR=0 QUADEN=1 flag=1
ftm-quaddec C0SC=85 C1SC=85 ftm_filter=ffff

I wonder if anybody has gotten these filters working?

static int initialize_ftm_quaddec(void __iomem *ftm_base)
{
uint8_t flag = 0x0;

clear_write_protection(ftm_base);

/* Do not write in the region from the CNTIN register through the
PWMLOAD register when FTMEN = 0. */
ftm_write(ftm_base,FTM_MODE, FTM_MODE_FTMEN);

/* Set the CTNIN - MOD range 0x0000-0xFFFF */
ftm_write(ftm_base,FTM_CNTIN, 0x0);
ftm_write(ftm_base,FTM_MOD, 0xffff);
/* Reset CNT to CNTIN by writing any value */
ftm_write(ftm_base,FTM_CNT, 0x0);

flag = 0x0;
/* interrupts not used;  */
/* Prescale divide by 1 => 0 */
/* Stop the clock CLKS */
flag |= FTM_SC_PS_1;
ftm_write(ftm_base,FTM_SC, flag);

/* Set channels 0, 1, 2, and 3 to output compare mode */
ftm_write(ftm_base, FTM_C0SC, 0x14); /* channel 0 as output compare */
ftm_write(ftm_base, FTM_C1SC, 0x14); /* channel 1 as output compare */
ftm_write(ftm_base, FTM_C2SC, 0x14); /* channel 1 as output compare */
ftm_write(ftm_base, FTM_C3SC, 0x14); /* channel 1 as output compare */
ftm_write(ftm_base, FTM_FILTER, 0xffff); /* max filter on PHA and PHB */

flag = 0x0;
/* input filters not used */
/* use normal polarity */
/* Phase A and Phase B encoding mode */
flag |= FTM_QDCTRL_QUADEN; /* QUADEN Enable Quadrature Decode mode */
flag |= FTM_QDCTRL_PHAFLTREN; /* enable PHA filter */
flag |= FTM_QDCTRL_PHBFLTREN; /* enable PHB filter */
ftm_write(ftm_base,FTM_QDCTRL, flag);
decode_QDCTRL(ftm_base,NULL);

/* Reset channels 0, 1, 2, and 3 to input mode */
ftm_write(ftm_base, FTM_C0SC, 5); /* channel 0 as input */
ftm_write(ftm_base, FTM_C1SC, 5); /* channel 1 as input */
ftm_write(ftm_base, FTM_C2SC, 5); /* channel 1 as input */
ftm_write(ftm_base, FTM_C3SC, 5); /* channel 1 as input */

decode_QDCTRL(ftm_base,NULL);
decode_filters(ftm_base,NULL);

/* Unused features and reset to default section */
ftm_write(ftm_base,FTM_POL, 0x0); /* Define the POL bits. */
/* all channels active high */
ftm_write(ftm_base,FTM_FLTCTRL, 0x0); /* all faults disabled */
ftm_write(ftm_base,FTM_SYNCONF, 0x0); /* disable all sync */
ftm_write(ftm_base,FTM_SYNC, 0xffff);

/* lock the FTM */
set_write_protection(ftm_base);
return 0;

}

0 Kudos

944 Views
alexander_yakov
NXP Employee
NXP Employee
The following is said in LS1021A Reference Manual, Section 21.4.19: 
Writing to the FILTER register has immediate effect and must be done only when the channels 0, 1, 2, and 3 are not in input modes. Failure to do this could result in a missing valid signal.
I do not see where in your code you are changing channel mode. 
The default channel mode is input.


Have a great day,
Alexander
TIC

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

944 Views
martinhundebøll
Contributor II

Hi Alexander,

According to Section 21.4.6 in the reference manual, the module defaults to "Not Used" modes (FTM_CnSC[ELSnB:ELSnA] = 00), which I interpret as "not in input modes".

I have tried setting channels 0, 1, 2, and 3 to "Output Compare modes" by setting FTM_CnSC = 0x14 prior to setting FTM_FILTER:

/* Filter enable bits in FTM_QDCTRL aren't updated */
ftm_write(ftm_base, FTM_MODE, FTM_MODE_WPDIS | /* disable write protect */
                              FTM_MODE_FTMEN); /* enable FTM */
ftm_write(ftm_base, FTM_CNTIN, 0x0);           /* zero init value */
ftm_write(ftm_base, FTM_MOD, 0xffff);          /* max overflow value */
ftm_write(ftm_base, FTM_CNT, 0x0);             /* set counter value */
ftm_write(ftm_base, FTM_SC, FTM_SC_PS_1);      /* prescale with x1 */

/* Set channels 0, 1, 2, and 3 to output compare mode */
ftm_write(FTM_C0SC, 0x14);   /* channel 0 as output compare */
ftm_write(FTM_C1SC, 0x14);   /* channel 1 as output compare */
ftm_write(FTM_C2SC, 0x14);   /* channel 1 as output compare */
ftm_write(FTM_C3SC, 0x14);   /* channel 1 as output compare */

ftm_write(ftm_base, FTM_FILTER, 0xff);         /* max filter on PHA and PHB */

/* this write seems to have no effect on the two filter bits? */
ftm_write(ftm_base, FTM_QDCTRL, FTM_QDCTRL_QUADEN |    /* select quad mode */
                                FTM_QDCTRL_PHAFLTREN | /* enable PHA filter */
                                FTM_QDCTRL_PHBFLTREN); /* enable PHB filter */

ftm_write(ftm_base, FTM_MODE, FTM_MODE_FTMEN); /* enable FTM (enable WP) */

Changing the channel modes makes no difference regarding the PHxFLTREN bits not being written to the FTM_QDCTRL register.

0 Kudos

944 Views
martinhundebøll
Contributor II

I tried following the example from Section 3.10 ('Quadrature decoder mode') from http://cache.freescale.com/files/32bit/doc/app_note/AN5142.pdf (AN5142.PDF), but I still cannot set the filter-enable bits of the QDCTRL register:

//using FTM1 as quadrature module, enable FTM0 and FTM1 clock
SIM_SCGC6|=0x03000000; //enable FTM0 and FTM1 module clock
FTM1_SC=0x00; //initialize the FTM1 module as quadrature mode
FTM1_MOD=20;
FTM1_CNTIN=0x00;
FTM1_C0SC=0x00;
FTM1_C1SC=0x00;
FTM1_QDCTRL|=0xC1; //enable quadrature mode
FTM1_MODE|=0x05; //enable FTM1 module
//quadrature mode which PhaseA and PhaseB signal have 90 degree shift
FTM1_SC=0x48; //enable counter overflow interrupt
0 Kudos