kinetis kL: problem in capture mode

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

kinetis kL: problem in capture mode

1,508 Views
stefanomanca
Contributor III

Hi, I need to measure a pulse (see the image) so I config a TPM in capture mode, at the begin rising edge interrupt is active, when I enter in the ISR, falling edge interrupt is actived. When a falling edge comes I stay in the ISR for a certain delay (guard time) so I avoid to capture noise. But as soon as I exit from ISR a while after the ISR is called again. It is like there was a pending bit,but that's impossible because before to exit I reset the pending bit (TPM0_C0SC |= (0x80);). It doesn't happen if I disable the interrupt by TPM0_C0SC |= (0x40); but in theory it shouldn't be necessary and anyway interrupt flag keep on working.

What happening? Any idea?

Thank you very much

capture.png

Tags (3)
0 Kudos
13 Replies

969 Views
Paul_Tian
NXP Employee
NXP Employee

Hi, Stefano

The TPM moduile (timer module) in KL series has a mode for input capture function. In Table Mode, Edge, and Level Selection, you can find setting for capture on rising and falling edge. It is not a good way for coding stay a long time in ISR. You can run out ISR, then check the period of pulse in your main loop. For your noise issue, you can set a pulse length value filter. If the calculated value is not higher than this filter value, you can ignore it.

Hope my reply can help you.

Best Regards

Paul

0 Kudos

969 Views
stefanomanca
Contributor III

Hi Zhe, could you see the answer given to Ping?

Thank you.

0 Kudos

969 Views
jeremyzhou
NXP Employee
NXP Employee

Hi Stefano,

I have had a brief look through your thread,I'm afraid that I'm not totally understand your question. So would it be possible for you to describle your question again?

I'm looking forward your reply.

Have a good day!

Best regards,

Ping

0 Kudos

969 Views
stefanomanca
Contributor III

Hi again, I send you the true cases images.

bad case.pngGOOD CASE.png

0 Kudos

969 Views
jeremyzhou
NXP Employee
NXP Employee

Hi Stefano,

I've had a careful look through your reply. Regard to the two screenshots, I'm also surprize about that and it seems like the flag can't been clean when two bad pulse happen.

I haven't figured out the issue so far, but I'd like to suggest you should consider Paul's advice which could make your workaround better.

I'll talk with other colleagues about this issue, so be patient.

Have a nice day.

Best regards,

Ping

0 Kudos

969 Views
jeremyzhou
NXP Employee
NXP Employee

Hi Stefano,

Thanks for your reply!

I'm also curious about this issue.However would it be possible for you to describe the new issue you had found more clearly? As I'm a little confuse about it.

I'm wondering if you could send me your project for me, then I could test it on my board!

I'm looking forward to your reply!

Have a nice weekend!

Best regards

0 Kudos

969 Views
stefanomanca
Contributor III

I think, I've already sent you my projects. Anyway, give me your mail please

0 Kudos

969 Views
jeremyzhou
NXP Employee
NXP Employee

Hi Stefano,

Sorry for delay reply, because I'm on Spring Festival vacation. Regarding your issue, I've created a project to simulate the issue which you had encounted, then could make me to figure out the reason of the issue more easily. However the issue didn't happen on my board. The detail of my project as follows:

Using the channel 3 of TPM1 to generate the PWM whose period is 1.068ms and the PWM will be measured by TPM1 after PTA12 connect PTC4.

In my project, the period of guard time is longer than the twice PWM period, so it's certainly that two period pulse will arrive the PTC4 during the guard time.

I've also included the project and test result with the reply, please refer to it for details.

If you have any other question, just contact with me directly.

Have a nice day!

Best regards,

Ping

0 Kudos

969 Views
stefanomanca
Contributor III

Hi Ping, I've found out who sets bit in nvic, are the following instructions:

TPM0_C0SC = 0x00U;

status = TPM0_C0SC;

while(status){

  status = (TPM0_C0SC & 0x3C);

}

TPM0_C0SC = 0x44;//after this nvic gets set

At this point I wonder how pass from rising edge interrupt enable to falling edge interrupt enable???

Thank you.

0 Kudos

969 Views
stefanomanca
Contributor III

Hi Ping, another super news. I don't know if it is an anomaly of kl family but if yes I want a reward from Freescale :-)

I noted a thing: when I enter in ISR then I do TPM0_C0SC |= (0x80); pending bit goes to 0 but in the interrupt vector keep on set so, if I do also NVIC_ICPR = 0x00020000; I don't enter again in the ISR.

I'm not so skilled but never in my life I see a similar behavior. What's your opinion??

Thank you.

0 Kudos

969 Views
stefanomanca
Contributor III

Hi Ping, I send you two projects for frdm-kl25z (how send .rar??), the first generate 2 pulse on ptb2 pressing a button on ptb0, the second config ptc1 as input capture. Put breakpoints like in the picture. You are going to see the first stop on bkp B then on bkp A but in th is case you wont see any pending interrupt. Very very strange.

breackpoints.png

0 Kudos

969 Views
stefanomanca
Contributor III

Hi Ping, I have news....crazy news.

What I see from osciloscope is that when I enter in my ISR because of a falling/rising edge after a while I exit from ISR, again the ISR is called but this time not for a rising/falling edge like there were another interrupt source but  TMP0_C0SC_CHF=0 and TMP0_SC_TOIE=0 (overflow interrupt disabled). Try yourself: generate a rising edge, then if( (TPM0_C0SC & 0X80)){toggle a pin}else{toggle another pin);you will see you will enter in the ISR twice.

0 Kudos

969 Views
stefanomanca
Contributor III

Hi Ping, I show you my pseudo-code:

TPM_ISR{

if((TPM0_C0SC & 0x4)){//if coming from a rising edge....

     TPM0_CNT = 0X0;//reset counter

     /* I'm not sure if that is correct,but the manual says:"When switching from one

        channel mode to a different channel mode, the channel must first be disabled and this

         must be acknowledged in the LPTPM counter clock domain." So I do this little code to switch from rising edge interrupt to falling edge interrupt.

        If I don't do this, the code lose  edges.

    */

    TPM0_C0SC = 0x00U;

    status = TPM0_C0SC;

    while(status){

        status = (TPM0_C0SC & 0x3C);

    }

   TPM0_C0SC |= 0x48;//falling edge interrupt enable

}else{//if coming from a falling edge

    pulse_period = TPM0_CNT;//pulse measure

    TPM0_C0SC = 0x00U;

    status = TPM0_C0SC;

    while(status){

    status = (TPM0_C0SC & 0x3C);

    }

   TPM0_C0SC = (TPM_CnSC_CHIE_MASK | TPM_CnSC_ELSA_MASK);//rising edge interrupt enable

   TPM0_CNT = 0;

   counter = 0;

   guard_time = 1000;

   while(counter < guard_time){

      counter = TPM0_CNT;

   }

}

TPM0_C0SC |= (0x80);//reset interrupt flag

}//end TPM_ISR

As you can see, after the guard time I reset the possible pending (rising/falling)interrupt but as soon as I exit from ISR, the ISR is called again like there were a pending interrupt.

That happens only if the situation is like that showed in the image: two unwanted pulse; but if there is only one unwanted pulse all goes well. It is like in the guard time the pending interrupts were queued and TPM0_C0SC |= (0x80); only deletes one.

Only work if i disable interrupt by TPM0_C0SC &= (~0x40); before the guard time and then I re-enable it when guard time elapsed.

I'm getting crazy.

Thank you.capture.png

0 Kudos