MPC5744 etimer capture fail in one channal

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

MPC5744 etimer capture fail in one channal

1,389 Views
pingli
Contributor III

Hi,NXP

look the file ,6 Measure signal parameters:

void eTimer_Init(uint8_t EtimerN,uint8_t DspiNumber)
{
volatile struct ETIMER_tag *pETIMERn;

switch(EtimerN)
{ //choose base eTimer address
case 0 : pETIMERn = &ETIMER_0; break;
case 1 : pETIMERn = &ETIMER_1; break;
case 2 : pETIMERn = &ETIMER_2; break;
default: pETIMERn = &ETIMER_0; break;
}


pETIMERn->ENBL.R = 0x0; // disable Timer0 channels

/* Configure the channel */
// pETIMERn->CH[DspiNumber].CTRL1.R = 0x38C1;//0x2001;//0x3801; // Counts only rising edge of the MC_CLK (100MHz in RUN0), divide by 1, count up, count repeatedly, rollover
pETIMERn->CH[DspiNumber].CTRL1.B.PRISRC = 0x18;
pETIMERn->CH[DspiNumber].CCCTRL.B.CPT1MODE = 2;
pETIMERn->CH[DspiNumber].CCCTRL.B.CPT2MODE = 1;
pETIMERn->CH[DspiNumber].CTRL1.B.LENGTH = 0;
pETIMERn->CH[DspiNumber].CTRL1.B.ONCE = 0;
pETIMERn->CH[DspiNumber].CTRL1.B.SECSRC = DspiNumber;
pETIMERn->CH[DspiNumber].CTRL1.B.CNTMODE = 1;

pETIMERn->CH[DspiNumber].COMP1.R = 0xFFFF;
pETIMERn->CH[DspiNumber].CCCTRL.R = 0x0264; // compare on COMP1 when counting up, COMP2 when counting down
// CAPT2 on falling edge, CAPT1 on rising edge, 2 entries
// free-running mode
/*
pETIMERn->CH[DspiNumber].CCCTRL.B.ONESHOT = 1;
pETIMERn->CH[DspiNumber].CCCTRL.B.CFWM = 2;


pETIMERn->CH[DspiNumber].CTRL3.R = 1;
pETIMERn->CH[DspiNumber].CTRL3.B.ROC = 3;

pETIMERn->ENBL.B.ENBL |= (1<<DspiNumber); // Enable Timer0 channel 1
pETIMERn->CH[DspiNumber].CCCTRL.B.ARM = 1; // starts the input capture process
//pETIMERn->CH[DspiNumber].CCCTRL.B.ONESHOT = 1;
*/
}

void eTimer_EnableChannal(uint8_t eTimerN,uint8_t DspiNumber)
{
volatile struct ETIMER_tag *pETIMERn;

switch(eTimerN)
{ //choose base eTimer address
case 0 : pETIMERn = &ETIMER_0; break;
case 1 : pETIMERn = &ETIMER_1; break;
case 2 : pETIMERn = &ETIMER_2; break;
default: pETIMERn = &ETIMER_0; break;
}

pETIMERn->ENBL.B.ENBL |= (1<<DspiNumber); // Enable Timer0 channel 1
}

void eTimer_Value(uint8_t EtimerN,uint8_t DspiNumber)
{
uint32_t counts;
uint32_t capture_ch[4];
uint8_t eTimerSTS = 0;

float freq,period,duty,pulseH,pulseL;

volatile struct ETIMER_tag *pETIMERn;
eTimer_Channal.duty = 0;
eTimer_Channal.Freq = 0;
eTimer_Channal.Period = 0;

switch(EtimerN)
{ //choose base eTimer address
case 0 : pETIMERn = &ETIMER_0; break;
case 1 : pETIMERn = &ETIMER_1; break;
case 2 : pETIMERn = &ETIMER_2; break;
default: pETIMERn = &ETIMER_0; break;
}

pETIMERn->CH[DspiNumber].CCCTRL.B.ARM = 1;
while((pETIMERn->CH[DspiNumber].STS.B.ICF1 == 0x0)||(pETIMERn->CH[DspiNumber].STS.B.ICF2 == 0x0))
{ //(pETIMERn->CH[DspiNumber].STS.B.ICF1 == 0x0)||(pETIMERn->CH[DspiNumber].STS.B.ICF2 == 0x0)
// Delayms(100);
// if(!(0x0080 & pETIMERn->CH[DspiNumber].STS.R)) eTimerSTS = 1;
}
pETIMERn->CH[DspiNumber].CCCTRL.B.ARM = 0; // stop the input capture process
pETIMERn->CH[DspiNumber].STS.B.ICF1 = 0x1;
pETIMERn->CH[DspiNumber].STS.B.ICF2 = 0x1;


capture_ch[0] = pETIMERn->CH[DspiNumber].CAPT1.R; //First rising edge
capture_ch[1] = pETIMERn->CH[DspiNumber].CAPT2.R; //First falling edge
capture_ch[2] = pETIMERn->CH[DspiNumber].CAPT1.R; //Second rising edge
capture_ch[3] = pETIMERn->CH[DspiNumber].CAPT2.R; //Second falling edge


counts = capture_ch[2] - capture_ch[0];


eTimer_Channal.Freq = (float)(100000000.0/counts);
eTimer_Channal.Period = (counts / (float)100000.0)*1000000;

counts = capture_ch[1] - capture_ch[0];

pulseH = (counts /100000.0)*1000000;
// eTimer_Channal.duty = pulseH/period*100;
eTimer_Channal.duty = ((uint16_t)((capture_ch[1] - capture_ch[0])*1000)/(uint16_t)(capture_ch[2] - capture_ch[0]));

PWM:25Hz

why I get the  duty fail 

clipping

0 Kudos
5 Replies

931 Views
pingli
Contributor III

Hi,Pert

Thank you very much!

In the Example-MPC5744P-eTimer-frequency_measurement-v1_0-GHS614,

channal 0 input,why I   need konw" while(!(0x0080 & ETIMER_0.CH[1].STS.R))"

while(!(0x0080 & ETIMER_0.CH[1].STS.R)){} // wait for channel 1's capture2 flag
while(!(0x0080 & ETIMER_0.CH[0].STS.R)){}

0 Kudos

931 Views
pingli
Contributor III

Hi,Petr

void eTimer_Init(uint8_t EtimerN,uint8_t DspiNumber)
{
volatile struct ETIMER_tag *pETIMERn;

switch(EtimerN)
{ //choose base eTimer address
case 0 : pETIMERn = &ETIMER_0; break;
case 1 : pETIMERn = &ETIMER_1; break;
case 2 : pETIMERn = &ETIMER_2; break;
default: pETIMERn = &ETIMER_0; break;
}


pETIMERn->ENBL.R = 0x0; // disable Timer0 channels

/* Configure the channel */
// pETIMERn->CH[DspiNumber].CTRL1.R = 0x3804; // Counts only rising edge of the MC_CLK (100MHz in RUN0), divide by 1, count up, count repeatedly, rollover
pETIMERn->CH[DspiNumber].CTRL1.B.CNTMODE = 1;
pETIMERn->CH[DspiNumber].CTRL1.B.PRISRC = 0x1F;
pETIMERn->CH[DspiNumber].CTRL1.B.SECSRC = DspiNumber;

pETIMERn->CH[DspiNumber].COMP1.R = 0xFFFF;
pETIMERn->CH[DspiNumber].CCCTRL.R = 0x0264;
pETIMERn->CH[DspiNumber].CTRL3.R = 1;

// pETIMERn->CH[DspiNumber+1].CTRL1.R = 0xF004; // Counts only rising edge of the MC_CLK (100MHz in RUN0), divide by 1, count up, count repeatedly, rollover
pETIMERn->CH[DspiNumber].CTRL1.B.CNTMODE = 3;
pETIMERn->CH[DspiNumber].CTRL1.B.PRISRC = 0x10+DspiNumber;
pETIMERn->CH[DspiNumber].CTRL1.B.SECSRC = DspiNumber;
pETIMERn->CH[DspiNumber+1].COMP1.R = 0xFFFF;
pETIMERn->CH[DspiNumber+1].CCCTRL.R = 0x0264;
pETIMERn->CH[DspiNumber+1].CTRL3.R = 1;

/*
pETIMERn->CH[DspiNumber].CTRL1.B.PRISRC = 0x1F;
pETIMERn->CH[DspiNumber].CCCTRL.B.CPT1MODE = 2;
pETIMERn->CH[DspiNumber].CCCTRL.B.CPT2MODE = 1;
pETIMERn->CH[DspiNumber].CCCTRL.B.CFWM = 2;

pETIMERn->CH[DspiNumber].CTRL1.B.LENGTH = 0;
pETIMERn->CH[DspiNumber].CTRL1.B.ONCE = 0;
pETIMERn->CH[DspiNumber].CTRL1.B.SECSRC = DspiNumber;
pETIMERn->CH[DspiNumber].CTRL1.B.CNTMODE = 1;*/

// pETIMERn->CH[DspiNumber].COMP1.R = 0xFFFF;
// pETIMERn->CH[DspiNumber].CCCTRL.R = 0x0264; // compare on COMP1 when counting up, COMP2 when counting down
// CAPT2 on falling edge, CAPT1 on rising edge, 2 entries
// free-running mode

// pETIMERn->CH[DspiNumber].CCCTRL.B.ONESHOT = 1;

// pETIMERn->CH[DspiNumber].CTRL3.R = 1;
// pETIMERn->CH[DspiNumber].CTRL3.B.ROC = 3;

pETIMERn->ENBL.B.ENBL |= (1<<DspiNumber)||(1<<(DspiNumber+1)); // Enable Timer0 channel 1
// pETIMERn->CH[DspiNumber].CCCTRL.B.ARM = 1; // starts the input capture process
//pETIMERn->CH[DspiNumber].CCCTRL.B.ONESHOT = 1;

}

void eTimer_EnableChannal(uint8_t eTimerN,uint8_t DspiNumber)
{
volatile struct ETIMER_tag *pETIMERn;

switch(eTimerN)
{ //choose base eTimer address
case 0 : pETIMERn = &ETIMER_0; break;
case 1 : pETIMERn = &ETIMER_1; break;
case 2 : pETIMERn = &ETIMER_2; break;
default: pETIMERn = &ETIMER_0; break;
}

pETIMERn->ENBL.B.ENBL |= (1<<DspiNumber); // Enable Timer0 channel 1
}

void eTimer_Value(uint8_t EtimerN,uint8_t DspiNumber)
{
double counts[2];
uint32_t capture_ch[4],capture_ch1[4],edge[5];
uint8_t eTimerSTS = 0;

double freq,period,duty,pulseH,pulseL;

volatile struct ETIMER_tag *pETIMERn;
eTimer_Channal.duty = 0;
eTimer_Channal.Freq = 0;
eTimer_Channal.Period = 0;

switch(EtimerN)
{ //choose base eTimer address
case 0 : pETIMERn = &ETIMER_0; break;
case 1 : pETIMERn = &ETIMER_1; break;
case 2 : pETIMERn = &ETIMER_2; break;
default: pETIMERn = &ETIMER_0; break;
}

pETIMERn->CH[DspiNumber].CCCTRL.B.ARM = 1;
pETIMERn->CH[DspiNumber+1].CCCTRL.B.ARM = 1;
while(!(0x0080 & pETIMERn->CH[DspiNumber].STS.R))
{ //(pETIMERn->CH[DspiNumber].STS.B.ICF1 == 0x0)||(pETIMERn->CH[DspiNumber].STS.B.ICF2 == 0x0)
// Delayms(100);
// if(!(0x0080 & pETIMERn->CH[DspiNumber].STS.R)) eTimerSTS = 1;
}
while(!(0x0080 & pETIMERn->CH[DspiNumber+1].STS.R))
{ //(pETIMERn->CH[DspiNumber].STS.B.ICF1 == 0x0)||(pETIMERn->CH[DspiNumber].STS.B.ICF2 == 0x0)
// Delayms(100);
// if(!(0x0080 & pETIMERn->CH[DspiNumber].STS.R)) eTimerSTS = 1;
}
// pETIMERn->CH[DspiNumber].CCCTRL.B.ARM = 0; // stop the input capture process
// pETIMERn->CH[DspiNumber].STS.B.ICF1 = 0x1;
// pETIMERn->CH[DspiNumber].STS.B.ICF2 = 0x1;

capture_ch[0] = pETIMERn->CH[DspiNumber].CAPT1.R; //First rising edge
capture_ch[1] = pETIMERn->CH[DspiNumber].CAPT2.R; //First falling edge
capture_ch[2] = pETIMERn->CH[DspiNumber].CAPT1.R; //Second rising edge
capture_ch[3] = pETIMERn->CH[DspiNumber].CAPT2.R; //Second falling edge

capture_ch1[0] = pETIMERn->CH[DspiNumber+1].CAPT1.R; //First rising edge
capture_ch1[1] = pETIMERn->CH[DspiNumber+1].CAPT2.R; //First falling edge
capture_ch1[2] = pETIMERn->CH[DspiNumber+1].CAPT1.R; //Second rising edge
capture_ch1[3] = pETIMERn->CH[DspiNumber+1].CAPT2.R; //Second falling edge

edge[1] = capture_ch1[0]*65536 + capture_ch[0]; // save 1st rising edge
edge[2] = capture_ch1[1]*65536 + capture_ch[1]; // save 1st falling edge
edge[3] = capture_ch1[2]*65536 + capture_ch[2]; // save 2nd rising edge
edge[4] = capture_ch1[3]*65536 + capture_ch[3]; // save 2nd falling edge

if(edge[3]>edge[1])
{
counts[0] = edge[3] - edge[1];
}
else
{
counts[0] = (0xFFFFFFFF - edge[1] +1) + edge[3];
}

eTimer_Channal.Freq = (float)100000000.0/counts[0];
eTimer_Channal.Period = counts[0] / (float)100000.0;

if(edge[2]>edge[1])
{
counts[1] = edge[2] - edge[1];
}
else
{
counts[1] = (0xFFFFFFFF - edge[1] +1) + edge[2];
}

pulseH = counts[1] / (float)100000.0;
pulseL = eTimer_Channal.Period-pulseH;

eTimer_Channal.duty = counts[1]*100/counts[0];//pulseH/eTimer_Channal.Period *100;


pETIMERn->CH[DspiNumber].STS.R = 0x00C0; // clear eTimern channel n's capture1/2 flags
pETIMERn->CH[DspiNumber+1].STS.R = 0x00C0; // clear eTimern channel n's capture1/2 flags
}

I get duty fail.

eTimer1 ,channal4;

Clipping

0 Kudos

931 Views
PetrS
NXP TechSupport
NXP TechSupport

you have wrong setting for cascaded channel, it should be

// pETIMERn->CH[DspiNumber+1].CTRL1.R = 0xF004; // Counts only rising edge of the MC_CLK (100MHz in RUN0), divide by 1, count up, count repeatedly, rollover
pETIMERn->CH[DspiNumber+1].CTRL1.B.CNTMODE = 7;
pETIMERn->CH[DspiNumber+1].CTRL1.B.PRISRC = 0x10+DspiNumber;
pETIMERn->CH[DspiNumber+1].CTRL1.B.SECSRC = DspiNumber;
pETIMERn->CH[DspiNumber+1].COMP1.R = 0xFFFF;
pETIMERn->CH[DspiNumber+1].CCCTRL.R = 0x0264;
pETIMERn->CH[DspiNumber+1].CTRL3.R = 1;

Also as you are using prescaler=128, you need to add this into relevant calculations.

BR, Petr

931 Views
PetrS
NXP TechSupport
NXP TechSupport

Hi,

If the channel is counting MC_CLK/1 (100MHz) and you measure 25Hz PWM signal, then expected counts per period will be 100e6 / 25 = 4 000 000 counts. The eTimer has just 16bit counter, thus for low frequency input signal you have to handle counter overflows or use slower internal counting clock (this way you will lose the precision).

 

Another possibility could be usage of cascaded counters, which serves overflow counting in HW.

The example using cascaded counters is here: https://community.nxp.com/docs/DOC-104285

BR, Petr

0 Kudos

931 Views
pingli
Contributor III

   Hi, Petr

Thank You!

void eTimer_Init(uint8_t EtimerN,uint8_t DspiNumber)
{
volatile struct ETIMER_tag *pETIMERn;

switch(EtimerN)
{ //choose base eTimer address
case 0 : pETIMERn = &ETIMER_0; break;
case 1 : pETIMERn = &ETIMER_1; break;
case 2 : pETIMERn = &ETIMER_2; break;
default: pETIMERn = &ETIMER_0; break;
}


pETIMERn->ENBL.R = 0x0; // disable Timer0 channels

/* Configure the channel */
// pETIMERn->CH[DspiNumber].CTRL1.R = 0x3804; // Counts only rising edge of the MC_CLK (100MHz in RUN0), divide by 1, count up, count repeatedly, rollover
pETIMERn->CH[DspiNumber].CTRL1.B.CNTMODE = 1;
pETIMERn->CH[DspiNumber].CTRL1.B.PRISRC = 0x1F;
pETIMERn->CH[DspiNumber].CTRL1.B.SECSRC = DspiNumber;

pETIMERn->CH[DspiNumber].COMP1.R = 0xFFFF;
pETIMERn->CH[DspiNumber].CCCTRL.R = 0x0264;
pETIMERn->CH[DspiNumber].CTRL3.R = 1;

// pETIMERn->CH[DspiNumber+1].CTRL1.R = 0xF004; // Counts only rising edge of the MC_CLK (100MHz in RUN0), divide by 1, count up, count repeatedly, rollover
pETIMERn->CH[DspiNumber].CTRL1.B.CNTMODE = 3;
pETIMERn->CH[DspiNumber].CTRL1.B.PRISRC = 0x10+DspiNumber;
pETIMERn->CH[DspiNumber].CTRL1.B.SECSRC = DspiNumber;
pETIMERn->CH[DspiNumber+1].COMP1.R = 0xFFFF;
pETIMERn->CH[DspiNumber+1].CCCTRL.R = 0x0264;
pETIMERn->CH[DspiNumber+1].CTRL3.R = 1;

/*
pETIMERn->CH[DspiNumber].CTRL1.B.PRISRC = 0x1F;
pETIMERn->CH[DspiNumber].CCCTRL.B.CPT1MODE = 2;
pETIMERn->CH[DspiNumber].CCCTRL.B.CPT2MODE = 1;
pETIMERn->CH[DspiNumber].CCCTRL.B.CFWM = 2;

pETIMERn->CH[DspiNumber].CTRL1.B.LENGTH = 0;
pETIMERn->CH[DspiNumber].CTRL1.B.ONCE = 0;
pETIMERn->CH[DspiNumber].CTRL1.B.SECSRC = DspiNumber;
pETIMERn->CH[DspiNumber].CTRL1.B.CNTMODE = 1;*/

// pETIMERn->CH[DspiNumber].COMP1.R = 0xFFFF;
// pETIMERn->CH[DspiNumber].CCCTRL.R = 0x0264; // compare on COMP1 when counting up, COMP2 when counting down
// CAPT2 on falling edge, CAPT1 on rising edge, 2 entries
// free-running mode

// pETIMERn->CH[DspiNumber].CCCTRL.B.ONESHOT = 1;

// pETIMERn->CH[DspiNumber].CTRL3.R = 1;
// pETIMERn->CH[DspiNumber].CTRL3.B.ROC = 3;

pETIMERn->ENBL.B.ENBL |= (1<<DspiNumber)||(1<<(DspiNumber+1)); // Enable Timer0 channel 1
// pETIMERn->CH[DspiNumber].CCCTRL.B.ARM = 1; // starts the input capture process
//pETIMERn->CH[DspiNumber].CCCTRL.B.ONESHOT = 1;

}

void eTimer_EnableChannal(uint8_t eTimerN,uint8_t DspiNumber)
{
volatile struct ETIMER_tag *pETIMERn;

switch(eTimerN)
{ //choose base eTimer address
case 0 : pETIMERn = &ETIMER_0; break;
case 1 : pETIMERn = &ETIMER_1; break;
case 2 : pETIMERn = &ETIMER_2; break;
default: pETIMERn = &ETIMER_0; break;
}

pETIMERn->ENBL.B.ENBL |= (1<<DspiNumber); // Enable Timer0 channel 1
}

void eTimer_Value(uint8_t EtimerN,uint8_t DspiNumber)
{
double counts[2];
uint32_t capture_ch[4],capture_ch1[4],edge[5];
uint8_t eTimerSTS = 0;

double freq,period,duty,pulseH,pulseL;

volatile struct ETIMER_tag *pETIMERn;
eTimer_Channal.duty = 0;
eTimer_Channal.Freq = 0;
eTimer_Channal.Period = 0;

switch(EtimerN)
{ //choose base eTimer address
case 0 : pETIMERn = &ETIMER_0; break;
case 1 : pETIMERn = &ETIMER_1; break;
case 2 : pETIMERn = &ETIMER_2; break;
default: pETIMERn = &ETIMER_0; break;
}

pETIMERn->CH[DspiNumber].CCCTRL.B.ARM = 1;
pETIMERn->CH[DspiNumber+1].CCCTRL.B.ARM = 1;
while(!(0x0080 & pETIMERn->CH[DspiNumber].STS.R))
{ //(pETIMERn->CH[DspiNumber].STS.B.ICF1 == 0x0)||(pETIMERn->CH[DspiNumber].STS.B.ICF2 == 0x0)
// Delayms(100);
// if(!(0x0080 & pETIMERn->CH[DspiNumber].STS.R)) eTimerSTS = 1;
}
while(!(0x0080 & pETIMERn->CH[DspiNumber+1].STS.R))
{ //(pETIMERn->CH[DspiNumber].STS.B.ICF1 == 0x0)||(pETIMERn->CH[DspiNumber].STS.B.ICF2 == 0x0)
// Delayms(100);
// if(!(0x0080 & pETIMERn->CH[DspiNumber].STS.R)) eTimerSTS = 1;
}
// pETIMERn->CH[DspiNumber].CCCTRL.B.ARM = 0; // stop the input capture process
// pETIMERn->CH[DspiNumber].STS.B.ICF1 = 0x1;
// pETIMERn->CH[DspiNumber].STS.B.ICF2 = 0x1;

capture_ch[0] = pETIMERn->CH[DspiNumber].CAPT1.R; //First rising edge
capture_ch[1] = pETIMERn->CH[DspiNumber].CAPT2.R; //First falling edge
capture_ch[2] = pETIMERn->CH[DspiNumber].CAPT1.R; //Second rising edge
capture_ch[3] = pETIMERn->CH[DspiNumber].CAPT2.R; //Second falling edge

capture_ch1[0] = pETIMERn->CH[DspiNumber+1].CAPT1.R; //First rising edge
capture_ch1[1] = pETIMERn->CH[DspiNumber+1].CAPT2.R; //First falling edge
capture_ch1[2] = pETIMERn->CH[DspiNumber+1].CAPT1.R; //Second rising edge
capture_ch1[3] = pETIMERn->CH[DspiNumber+1].CAPT2.R; //Second falling edge

edge[1] = capture_ch1[0]*65536 + capture_ch[0]; // save 1st rising edge
edge[2] = capture_ch1[1]*65536 + capture_ch[1]; // save 1st falling edge
edge[3] = capture_ch1[2]*65536 + capture_ch[2]; // save 2nd rising edge
edge[4] = capture_ch1[3]*65536 + capture_ch[3]; // save 2nd falling edge

if(edge[3]>edge[1])
{
counts[0] = edge[3] - edge[1];
}
else
{
counts[0] = (0xFFFFFFFF - edge[1] +1) + edge[3];
}

eTimer_Channal.Freq = (float)100000000.0/counts[0];
eTimer_Channal.Period = counts[0] / (float)100000.0;

if(edge[2]>edge[1])
{
counts[1] = edge[2] - edge[1];
}
else
{
counts[1] = (0xFFFFFFFF - edge[1] +1) + edge[2];
}

pulseH = counts[1] / (float)100000.0;
pulseL = eTimer_Channal.Period-pulseH;

eTimer_Channal.duty = counts[1]*100/counts[0];//pulseH/eTimer_Channal.Period *100;


pETIMERn->CH[DspiNumber].STS.R = 0x00C0; // clear eTimern channel n's capture1/2 flags
pETIMERn->CH[DspiNumber+1].STS.R = 0x00C0; // clear eTimern channel n's capture1/2 flags
}

I fail to get duty. (eTimer1,channal4);

Clipping

0 Kudos