eTimer by triggering interrupt on MPC5744P

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

eTimer by triggering interrupt on MPC5744P

1,212 Views
yixinwu
Contributor I

Hello community,

 

I have met some problems with using eTimer by triggering timer interrupt. (MPC5744P, 1N65H) Two signal inputs (A[0] and A[1]) are used for the measurement of motor speed. 3 channels of Etimer_0 have been used: channel 0 for quadrature mode to determine the current rotation direction, channel 1 for measurement of input A[0] signal length by using counting mode and channel 2 for measurement of A[1]. The configuration of eTimer channel 1 is shown as below (for channel 2 is similar).

 

  SIUL2.IMCR[59].SSS.B = 2; //input functionality
  SIUL2.MSCR[0].IBE.B = 1; //enable input buffer
  SIUL2.MSCR[0].OBE.B = 0; //disable output buffer
  SIUL2.MSCR[0].SRC = 0; //slew rate
 
  SIUL2.IMCR[60].SSS.B = 2; //input functionality
  SIUL2.MSCR[1].IBE.B = 1; //enable input buffer
  SIUL2.MSCR[1].OBE.B = 0; //disable output buffer
  SIUL2.MSCR[1].SRC = 0; //slew rate

  ETIMER_0.CH[1].LOAD.R = 0;                          // Reload to CNTR on capture 1 event
  ETIMER_0.CH[1].CTRL1.B.PRISRC = 0x1C;               // Primary count source
  ETIMER_0.CH[1].CTRL1.B.ONCE = 0;                    // Continue repeatedly
  ETIMER_0.CH[1].CTRL1.B.LENGTH = 0;                  // Continue counting to roll over
  ETIMER_0.CH[1].CTRL1.B.DIR = 0;                     // Count up
  ETIMER_0.CH[1].CTRL1.B.SECSRC = 0;      // Secondary count source = Motor speed sensor 1

  ETIMER_0.CH[1].CTRL2.B.OEN = 0;                     // Pin output disable
  ETIMER_0.CH[1].CTRL2.B.SIPS = 0;                    // Secondary input true polarity

  ETIMER_0.CH[1].CTRL3.B.ROC = 3;           // Reload counter from LOAD on capture 1 event

  ETIMER_0.CH[1].CCCTRL.B.CPT2MODE = 1;       // Capture falling edges of secondary source
  ETIMER_0.CH[1].CCCTRL.B.CPT1MODE = 2;         // Capture rising edge of secondary source
  ETIMER_0.CH[1].CCCTRL.B.CFWM = 1; //2;                  // Capture FIFO set to 1

  ETIMER_0.CH[1].INTDMA.B.ICF2IE = 1;                 // Enable INT request on CAPT2
  ETIMER_0.CH[1].INTDMA.B.ICF1IE = 1;                 // Enable INT request on CAPT1

 

At first I tried to ICF flags for detecting the signal edges. Therefore I activate the INTDMA.B.ICF1IE and INTDMA.B.ICF2IE for interrupt request. The capture mode is set as CPT1MODE for rising edge and CPT2MODE for falling edge. The problem is: Not every high and low edge can be detected by triggering the interrupts, and the captured signal length value is sometimes 0. No matter high edge or low edge, the flags ICF1 and ICF2 are not set correctly. The flags are sometimes both set to 1, although there was only one high edge. (For a high edge: ICF1=1 and ICF2=1 or ICF1=1 and ICF2=0)

 

void fn_etimer0_ch1_isr(void)
{
  g_uc_isrrunning = 1;  //indicate that ISR is active
 
  //ETIMER_0.CH[1].CCCTRL.B.ARM = 0;
 
  if(ETIMER_0.CH[1].STS.B.ICF1)
  {
    g_ustimecounter_inva = ETIMER_0.CH[1].CAPT1.R;
   
    g_usinva_edge_ctr++;
    g_usinvacounter++;
  }

  if(ETIMER_0.CH[1].STS.B.ICF2)
  {
    g_ustimecounter_inva1 = ETIMER_0.CH[1].CAPT2.R;
     
    g_usinva_edge_ctr++;
  }
   
  ETIMER_0.CH[1].STS.B.ICF1 = 1;
  ETIMER_0.CH[1].STS.B.ICF2 = 1;
 
  //ETIMER_0.CH[1].CCCTRL.B.ARM = 1;
 
  g_uc_isrrunning = 0;  //ISR is finished to be handeled
}

 

Then I tried the IEHFIE and IELFIE for the interrupt request. The capture mode is set as CPT1MODE for rising edge and CPT2MODE for falling edge. Here every high edge can be detected by triggering the interrupts, but the captured signal length value is still sometimes 0. For a high edge: IEHF=1 and IELF=0, this is perfect. But for a low edge: IEHF=1 and IELF=1, even ICF1 and ICF2 are both set to 1, although the interrupt should not be triggered by ICF.

 

For both cases the channel 0 works well, that the rotation direction can be determined correctly and stable.

 

A situation has been also observed that, if one of the ICF1, ICF2, IEHF, IELF flags is cleared by writing to 1, all 4 flags are cleared. Is this normal?

 

Would you please help me to solve these problems? Thank you very much.

Labels (1)
0 Kudos
3 Replies

599 Views
yixinwu
Contributor I

Thank you very much for the reply. I will change this not only for the eTimer part but also in my whole project and then check it again.

0 Kudos

599 Views
yixinwu
Contributor I

Hello Petr,

after long-time testing I have found my problem. For the eTimer inputs I have added the hysteresis feature and the signals can be counted and measure correctly now.

All bit clearings in the project have been modified to register access instead of bit access, so this problem is also solved.

The flags of ICF1 and ICF2 are not really set and reset as I want, if I try with very slow signal; but for fast signals the counting of pulses and the measurement of signal length are all correct. Why this? Should I add some filters? (The input signals are normal pulses from motor fly wheel sensors.)

Thank you in advance.

0 Kudos

599 Views
PetrS
NXP TechSupport
NXP TechSupport

Hi,

First of all do not use bit access for flag clearing, as this can clear other flags too.

You can see clear explanation in EB758 “Using Qorivva Header Files in C Avoiding Unexpected Operation” in chapter 3.2 Status bit clearing.

http://cache.freescale.com/files/32bit/doc/eng_bulletin/EB758.pdf

 

So modify your code and see the behavior then.

BR, Petr