S32K144 Quadrature Decoder Configuration Issue

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

S32K144 Quadrature Decoder Configuration Issue

2,597 Views
cjf6221
Contributor I

Hello Everyone,

I would like to used FTM2_QD(PTD10, PTD11) to measure every rising or falling edge of A and B by using counter overflow interrupt and then calculate the motor position based on encoder. But I am troubled by the FTM2_QD configuration for a long time. 

Below is my configuration for FTM2_QD. Please provide some help. 

 

void FTM2_Quadrature_Decoder_Mode()
{
/* Enable clock for PORTD */
PCC->PCCn[PCC_PORTD_INDEX] = PCC_PCCn_CGC_MASK;
/* Select and enable clock for FTM2 */
PCC->PCCn[PCC_FLEXTMR2_INDEX] = PCC_PCCn_PCS(6) | PCC_PCCn_CGC_MASK;

PORTD->PCR[10] = PORT_PCR_MUX(3); // Set PTD10 for FTM2 - Phase B input
PORTD->PCR[11] = PORT_PCR_MUX(3); // Set PTD11 for FTM2 - Phase A input

FSL_NVIC->ISER[FTM2_IRQn / 32] |= (1 << (FTM2_IRQn % 32)); // Enable FTM2 counter overflow interrupt
// FSL_NVIC->ICPR[116/32] = 1 << (116% 32);
FSL_NVIC->ISER[116/32] = 1 << (116% 32);   // overflow interrupt number
// FSL_NVIC->IP[116] = 0;

FTM2->MODE = FTM_MODE_WPDIS_MASK | FTM_MODE_FTMEN_MASK;

//Enable FTM2 module (0x00000005): D2(WPDIS) and D0(FTMEN) are set.

 

FTM2->MOD = FTM_MOD_MOD(10); // overflow after totally 4096 rising/falling edges
FTM2->CNT = 0;  
FTM2->CNTIN = FTM_CNTIN_INIT(0);

FTM2->QDCTRL &= ~FTM_QDCTRL_QUADMODE_MASK; // Phase A and phase B encoding mode
FTM2->QDCTRL = FTM_QDCTRL_PHAFLTREN_MASK | FTM_QDCTRL_PHBFLTREN_MASK | FTM_QDCTRL_QUADEN_MASK; // Enable QD mode and input filter
FTM2->SC |= FTM_SC_CLKS(1) | FTM_SC_PS(2) | FTM_SC_CPWMS_MASK | FTM_SC_TOIE_MASK;

// FTM_SC_CLKS(1): select FTM as input timer.
// FTM_SC_PS(2): clock source FTM, prescaler 2^2, clock frequency = 112MHz/4 = 28MHz
// FTM_SC_TOIE_MASK: enable timer overflow interruption
// FTM_SC_CPWMS_MASK; D5(CPWMS) is set to enable up-down counting mode
}

 

Below is the overflow interrupt function.

void FTM2_Ovf_Reload_IRQHandler()  
{

if( FTM2->SC & FTM_SC_TOF_MASK ){   // there is overflow interrupt
    PTC->PTOR |= 1<<9; // Toggle PTC9 for scope display
    FTM2_ISR_Counter++;
    Temp_EncoderB = FTM2->CONTROLS[0].CnV; //store the captured C0V value (Counter's vaule)
    Temp_EncoderA = FTM2->CONTROLS[1].CnV; //store the captured C1V value (Counter's vaule)
    FTM2->CONTROLS[0].CnSC &= ~FTM_CnSC_CHF_MASK; //clear Ch0 flag D7(CHF) is required to be reset after reading
    FTM2->CONTROLS[1].CnSC &= ~FTM_CnSC_CHF_MASK; //clear Ch1 flag D7(CHF) is required to be reset after reading
    Count_Encoder = FTM2->CNT;
    FTM2->SC &= ~FTM_SC_TOF_MASK; // Clear timer overflow flag D9(TOF) after reading the captured C0V and C0V1 values.

}

}

I do not know why there is no output for Temp_EncoderB and Temp_EncoderA. It sounds like the overflow interrupt does not happen. Please provide some help if you know.

Thanks.

 

Best,

Jianfei Chen

0 Kudos
Reply
10 Replies

2,312 Views
dianabatrlova
NXP TechSupport
NXP TechSupport

Hello Rong,

The interrupt does not work because you are using old code/header file where is used FSL_NVIC write.

The S32_NVIC should be used instead of FSL_NVIC in the new projects. 

I recommend you to create a new project. After that, the header file will be correct and you can use, for example, code below for initialization of the interrupt:

S32_NVIC->ICPR[3] = 1 << (116 % 32);
S32_NVIC->ISER[3] = 1 << (116 % 32);
S32_NVIC->IP[116] = 0x00;

I hope it helps.

Best Regards,

Diana

0 Kudos
Reply

2,312 Views
cjf6221
Contributor I

Hello Diana,

Thanks so much.

According to your suggest, I creat a new project in S32 Design Studio but it showed there is no "S32_NVIC". What is the problem ? Is it a must to replace FSL_NVIC by S32_NVIC ?

Best,

Jianfei

0 Kudos
Reply

2,312 Views
dianabatrlova
NXP TechSupport
NXP TechSupport

Hello Rong,

Which version of S32 Design Studio do you use?

Please, use the newest version S32 Design Studio for Arm 2018.R1:

https://www.nxp.com/webapp/swlicensing/sso/downloadSoftware.sp?catid=S32-DS-ARM_v2018  

Best Regards,

Diana

0 Kudos
Reply

2,312 Views
cjf6221
Contributor I

Maybe the problem is caused by the interruption type. I used overflow interruption, which maybe not suitable for quadrature encoder mode. What do you think ?

Best,

Jianfei

0 Kudos
Reply

2,312 Views
dianabatrlova
NXP TechSupport
NXP TechSupport

Hello Jianfei,

I really recommend you to install the newest version of the S32DS - S32 Design Studio for Arm 2018.R1 – Windows/Linux(REV 2018-R1), after that, it should work:

S32 Design Studio IDE for Arm® based MCUs | NXP 

Have you seen the maskset when you select the device in v1.3? I'm asking because the v1.3 generates the old header file where the FSL_NVIC is implemented.

Best Regards,

Diana

0 Kudos
Reply

2,312 Views
cjf6221
Contributor I

Hello Diana,

According to your suggestion, I have installed the newest version of S32DS. Below is the code built in S32-Arm2018.R1.


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

void FTM2_Quadrature_Decoder_Mode();
uint16_t Temp_EncoderA; //Port D11
uint16_t Temp_EncoderB; //Port D10
uint16_t FTM2_ISR_Counter=0;
uint16_t Count_Encoder = 0;
uint16_t Pre_Count_Encoder = 0;
uint16_t Count_Overflow,k;
uint8_t Motor_TOFDIR_Encoder, Motor_TOF_Encoder; // Timer overflow direction

int main(void)
{
int counter = 0;
FTM2_Quadrature_Decoder_Mode();

// for(;;) {
// }

/* to avoid the warning message for GHS and IAR: statement is unreachable*/
#if defined (__ghs__)
#pragma ghs nowarning 111
#endif
#if defined (__ICCARM__)
#pragma diag_suppress=Pe111
#endif
return 0;
}

void FTM2_Quadrature_Decoder_Mode()
{
/* Enable clock for PORTD */
PCC->PCCn[PCC_PORTD_INDEX] = PCC_PCCn_CGC_MASK; // clock enabled
/* Select and enable clock for FTM2 */
PCC->PCCn[58] |= PCC_PCCn_PCS(6) | PCC_PCCn_CGC_MASK;
// PORTD->PCR[4] |= PORT_PCR_MUX(1) | PORT_PCR_IRQC(9);

PORTD->PCR[10] |= PORT_PCR_MUX(3); // Set PTD10 for FTM2 - Phase B input
PORTD->PCR[11] |= PORT_PCR_MUX(3); // Set PTD11 for FTM2 - Phase A input

// S32_NVIC->ISER[3] |= (1 << (FTM2_IRQn % 32)); // Enable FTM2 interrupt FTM2_IRQn
S32_NVIC->ICPR[3] = (1<<(116%32)); //116/32=3 /* clr any pending IRQ*/
S32_NVIC->ISER[3] = (1<<(116%32)); //116/32=3 /* enable IRQ */
S32_NVIC->IP[116] = 0x00;

/* Input capture mode sensitive on both rising and falling edges to measure duty cycle of tested signal */

FTM2->MODE |= FTM_MODE_WPDIS_MASK | FTM_MODE_FTMEN_MASK; // Enable write the FTM CnV register (0x00000004): D2(WPDIS)
// Enable FTM2 module (0x00000001): D0(FTMEN) are set.FTM_MODE_INIT_MASK
//enable the counter to run in the BDM mode
//FTM2->CONF = FTM_CONF_BDMMODE(3);
/* Encoder simulation with totally 144 rising/falling edges */
FTM2->MOD = FTM_MOD_MOD(10);
/* Reset counter */
FTM2->CNTIN = FTM_CNTIN_INIT(0); // initial value of FTM2 counter
FTM2->QDCTRL &= ~FTM_QDCTRL_QUADMODE_MASK; // Phase A and phase B encoding mode
FTM2->QDCTRL |= FTM_QDCTRL_QUADEN_MASK; // Enable QD mode.
FTM2->QDCTRL &= ~FTM_QDCTRL_TOFDIR_MASK;
FTM2->CNT = 0;
/* Select clock */
FTM2->SC |= FTM_SC_CLKS(1) | FTM_SC_PS(4) | FTM_SC_TOIE_MASK;
// FTM_SC_CLKS(1) selects FTM as input timer.
// FTM_SC_PS(2); clock source FTM, prescaler 2^2, clock frequency = 112MHz/4 = 28MHz
// FTM_SC_TOIE_MASK enables timer overflow interruption
// FTM_SC_CPWMS_MASK; D5(CPWMS) is set to enable up-down counting mode FTM_SC_CPWMS_MASK
}

void FTM2_Ovf_Reload_IRQHandler()//this interrupt is FTM2
//void FTM2_Ch0_Ch1_IRQHandler()//this interrupt is FTM2
{
PTA->PTOR |= 0x0800; //PTA11 is set
if(FTM2->SC & FTM_SC_TOF_MASK ){
Motor_TOFDIR_Encoder = ((FTM2->QDCTRL)>>1)&0x1; // the QUADIR bit in the FTM_QDCTRL register indicates Timer overflow direction in QD mode
Motor_TOF_Encoder = ((FTM2->SC)>>9)&0x1; // Timer overflow flag
if(Motor_TOFDIR_Encoder){
Count_Overflow++;
}else{
Count_Overflow--;
}
Pre_Count_Encoder = Count_Encoder;
Count_Encoder = Count_Encoder*10 + FTM2->CNT;
FTM2->SC &= ~FTM_SC_TOF_MASK; // Clear timer overflow flag D9(TOF) is reset
}
PTA->PTOR &= 0x7FFF; //PTA11 is reset
}

I debuged it in Debug_RAM mode and found it cannot enter the overflow interrupt. So FTM2->CNT has no change. I also tried another interrupt FTM2_Ch0_Ch1_IRQHandler() but still cannot enter the interrupt. I was troubled by this issue for so long time. 

Best,

Jianfei

0 Kudos
Reply

2,312 Views
dianabatrlova
NXP TechSupport
NXP TechSupport

Hello Rong,

I have attached a very simple test code. I'm using S32K144EVB.

There I verify that after the FTM counter reach number 36 (0x24) the interrupt is generated.

pastedImage_1.png

I hope it helps.

Best Regards,

Diana

0 Kudos
Reply

2,312 Views
cjf6221
Contributor I

Hi Diana,

Thanks for your patience and kind help. Finally I figured it out and found the FTM2 should be configured to work under debug mode as I would like to debug it under the debug_RAM mode. So the following code must be added.

 FTM2->CONF = FTM_CONF_BDMMODE(3); 

 

Under this way, the overflow interrrupt is set as follows:

pastedImage_1.png

Then, quadrature decoder works well and there is the same result as you attached. FTM2->CNT successfully changes.

pastedImage_3.png

But here I have one more question. I used overflowed interrupt (TOF) but you suggested reload interrupt (RF) with the code as follows:

pastedImage_2.png

 

Interestingly, the output results are the same. Can you explain why this happen ?

0 Kudos
Reply

2,312 Views
dianabatrlova
NXP TechSupport
NXP TechSupport

Hi Rong, 

I'm very sorry for the delay. I'm glad that it works.

Actually I'm using TOIE - overflowed interrupt in this code. I'm using this code as a test code (it is not an official example) so, the clearing reload flag RF it's unnecessary. It should not be there. I'm sorry I confused you. There should be clearing TOF.

If you have the interest to know more about reload interrupt I recommend you to read sections in the RM rev 11:

45.5.29 Reload Points and 45.5.29.1 Reload Opportunities

Best Regards,

Diana

0 Kudos
Reply

2,312 Views
cjf6221
Contributor I

Hello Diana,

Thanks so much. The version I used is Arm V1.3. As you said, quadrature encoder is not availablel in Arm V1.3 ?

Best,

Jianfei

0 Kudos
Reply