AnsweredAssumed Answered

eTimer by triggering interrupt on MPC5744P

Question asked by Yixin Wu on Sep 9, 2016
Latest reply on Sep 28, 2016 by Yixin Wu

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;
    g_ustimecounter_inva = ETIMER_0.CH[1].CAPT1.R;

    g_ustimecounter_inva1 = ETIMER_0.CH[1].CAPT2.R;
  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.