delay larger than the timer time set on a pin

cancel
Showing results for 
Search instead for 
Did you mean: 

delay larger than the timer time set on a pin

1,156 Views
mehdikarimibiuk
Contributor V

I have MK60DN512VLL10. It runs at full speed 100MHz in PEE mode.

I am using a timer for to reset a GPIO pin. On time counter_restart, I toggle the value of the gpio. But when I probe the gpio I see that it is showing me larger time than what I set in the time. Why is that?

Labels (1)
Tags (3)
21 Replies

422 Views
santiago_lopez
NXP Employee
NXP Employee

Hi Mehdi


Which timer are you using? How are you configuring it? Some timers have the option to select different clock sources (Low Power Oscillator, PLL/FLL output, Bus Clock, etc...). The count period of your timer will depend on the clock source used. This frequency also modifies if you configure prescaler values to divide the input frequency.

Also, how fast are you trying to change the GPIO pin value? The GPIO pins have a rise/fall time that needs to be considered at high frequencies (MHz). A good test is configure your timer to change on a low fixed frequency (i.e. 10Khz) and change the GPIO value on the interrupt. Then measure the period value on the scope and determine the difference with the period you are expecting. For example, if you configure the timer to change the GPIO value @10Khz and you get a 5Khz frequency, you may have a by 2 divider configured somewhere.


Saludos


Santiago Lopez

0 Kudos

422 Views
mehdikarimibiuk
Contributor V

n/a

0 Kudos

422 Views
santiago_lopez
NXP Employee
NXP Employee

The PIT uses the Bus Clock to decrement the counter. The amount of time the GPIO remains set will depend on the value of PIT_LDVALn and the Bus Clock period according with the formula:

LDVAL trigger = (period/clock period)-1

For example, assuming you have a Bus Clock Frequency of 50MHz (0.02uS) and you want the PIT to interrupt after 1uS you replace:

LDVAL = (1uS/0.02uS)-1 = 49

I suppose that you are using Processor Expert. Check your clock configuration to determine the Bus Clock frequency and use that value to determine the value of LDVAL. For your reference, attached you will find a project I did using Processor Expert and CodeWarrior 10.6. It is configured for MK60N512Z using an external 8MHz clock. PTC11 toggles every 1uS using PIT with Bus Clock = 50MHz, Core/System clock = 100MHz (MCG on PEE @100MHz)

Saludos

Santiago Lopez

422 Views
mehdikarimibiuk
Contributor V

Hi

I looked at your project. Unfortunately I cannot use your PIT init since I am having 2 more component using PIT. Is there any other possible way to do this?

Moreover, I sometimes need to only toggle a signal. Is it possible to turn off the timer when not needed for this? Would you have an example for this?

Thanks

Mehdi

0 Kudos

422 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

You run the K60 in 100Mhz, 1uS only take 100 clock cycles, when you use interrupt to clear the GPIO pin, you have to consider the interrupt cost and clearing GPIO instruction itself as Mr Santiago Lopez said. If you generate for example 1mS pulse even 1s pulse, it will be very accurate, because the cost of interrupt is small compared with the pulse width itself. you can use FTM to generate precise 1us pulse.

I think the 100MHz clock frequency is precise, because you use external crystal.

0 Kudos

422 Views
mehdikarimibiuk
Contributor V

Because of the issues explained above, it seems that I cannot use FTM. Is it possible to use SysTick instead. Would you have any example for this. As said I only want PTE0 to go low for 1us wherever in my code I tell it.

0 Kudos

422 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

The interrupt latency is a constant value, no matter whether you use PIT or System timer modules, the interrupt latency can not be improved even if you use system timer although the System timer is a core module and has higher priority.

As Mr Santiago Lopez suggested, you can shorten the cycle time saved in PIT load

//systick configuration
  SYST_RVR=0x30000;
  SYST_CVR=0x30000;
  SYST_CSR|=0x04;
  SYST_CSR|=0x02;
  asm("nop");
// asm("cpsie i");
  SYST_CSR|=0x01;
  for(k=0;k<5000;k++)
  {
      asm("nop");
  }
  counter=SYST_CVR;

#pragma interrupt on
void ISR_systick(void)
{
   
    asm("nop");
    GPIOE_PTOR|=0x01;
//    Bits1_NegBit();    //toggle GPIOE0 pin
}

you have to update the vector table.

422 Views
mehdikarimibiuk
Contributor V

I tried with PIT_CVAL0 and the minimum I can get to is between 1-3us. As you said above there is an overhead for interrupt vector updating and pin driving. But the question is, can I go below 1us for interrupt updating and gpio driving, that is, 1us translates to 100 clock cycles for my 100MHz processor to update the interrupt vector and drive gpio. In other words I cannot go equal of below 1us, is this true?

Now, if I want to use this approach, can you tell me if I can use external clock source?:

Is this my external clock? or external clock of the module? Can I configure this? I am confused for this. Can you please explain?

I am using PEE mode at 100MHz core and 50MHz bus clock.

My chip is MK60DN512VLL10.

Thanks

0 Kudos

422 Views
mehdikarimibiuk
Contributor V

n/a

0 Kudos

422 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

I think the code which PE generated has a lot of lengthy code which almost make it possible to generate 1us delay:

the following is the code based on PE:

Original code:

void BlinkTimer_OnCounterRestart(LDD_TUserData *UserDataPtr)
{
  /* Write your code here ... */
    //Bit1_NegVal(NULL);
    Bit1_ClrVal(NULL);
    BlinkTimer_Disable(NULL);
    //asm("nop");
}

after compiled by CW, the following is the assembly code:

          BlinkTimer_OnCounterRestart:
78       {
20000648:   push {r7,lr}
2000064a:   sub sp,sp,#8
2000064c:   add r7,sp,#0
2000064e:   str r0,[r7,#4]
81           Bit1_ClrVal(NULL);
20000650:   mov r0,#0x0
20000654:   bl Bit1_ClrVal (0x20000540); 0x20000540
82           BlinkTimer_Disable(NULL);
20000658:   mov r0,#0x0
2000065c:   bl BlinkTimer_Disable (0x20000438); 0x20000438
84       }

I suggest you write a simple code without PE..

0 Kudos

422 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Furthermore, the PIT should use BUS clock as it's driving clockk, which can reach up to 50mHz rather than 100MHz, The core/system clcok can reach up to 100MHz.

422 Views
mehdikarimibiuk
Contributor V

n/a

0 Kudos

422 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

I wrote a simple isr without PE, it can generate 1us pusle cycle time. Pls refer to the attached file.

422 Views
mehdikarimibiuk
Contributor V

n/a

0 Kudos

422 Views
santiago_lopez
NXP Employee
NXP Employee

Hi Mehdi,

So, you want to call a function that changes the PIN polarity for 1uS and then change it back until you call that function again, am I right? In that case we don´t recommend to use interrupts since it takes some clock cycles to the MCU for entering the interrupt vector. Instead, we recommend you to use the Flex Timer Module (FTM). This module includes a special characteristic, the PWM combine mode. This allows you to toggle a pin when the CHn Value is reached, and then toggle it again when the value of CHn+1 is reached. For example, you can set the CH0 to 0 so the pin value toggles immediately, and configure the CH1 to 1uS to toggle the pin back after that time. You can find more information about this characteristic in the K60 Reference Manual Section 39.4.8 Combine Mode.

I have attached an example application. The output pin is PTB9. It is using FTM2 and the pulse is generated when a falling edge is detected in PTC0 (used as external interrupt).

Let me know if this solution works for you.

Saludos

Santiago Lopez

0 Kudos

422 Views
mehdikarimibiuk
Contributor V

My output pin must be PTE0.

And I do not need any other extra pin.

for example:

if my board temperature is higher than expected, signal PTE0 for 1us. PTE0 is high all the time and goes low for 1us when said to be.

0 Kudos

422 Views
santiago_lopez
NXP Employee
NXP Employee

Hi Mehdi

You are right, it is PTB19, sorry for the typo.

Since you are using the FTM combine mode, you will be able to use only the pins marked as FTMx_CHn for the selected modules and channels.


In the example I sent you, we are using FTM2 and the channels 0 and 1 for the combine mode, so you will be able to use only the pins that offer outputs for those channels. In this case those are PTB18 and PTB19 as shown in the PIN muxing table on chapter 10 of the Reference Manual.


Pin Muxing.PNG.png

So, if required, you can use any pin marked as FTMx_CHn by configuring the proper FTM module and channels for combine operation.

Said that, my recomendation for you is to change PTE0 with one of the FTMx_CHn pins. If you use PTE0, you won´t be able to use this FTM characteristic. The only option I see would be to determine how much does it takes to the MCU to enter the Timer Interrupt, then configure your timer to compensate that time. For example:

It takes to your MCU 400nS to enter the interrupt (hipotetical value)

You configure your timer to generate a IRQ after 600nS instead of 1uS

So your timer interrupts after 600nS + 400nS it takes to enter the IRQ = 1uS you need.

Please notice that using this approach does not guarantee precise 1uS periods since you will not only depend on the timer.

Saludos

Santiago Lopez

0 Kudos

422 Views
mehdikarimibiuk
Contributor V

Unfortunately we cannot change our GPIOs. Both of our PTB18 and PTB19 are used for different purposes and PTE0 is assigned to interrupt an external device. The external device will look at if PTE0 goes low for 1us, it takes it as an interrupt.

I looked at timing overhead that interrupt and setting gpio api apply. They are large compared to 1us that I want. They make my interrupt somewhere between 10-30us.

Is it not possible to use system ticks instead of using timer modules?

0 Kudos

422 Views
mehdikarimibiuk
Contributor V

I think you are using PTB19 not PTB9, is that right? If so, I have already used PTB19, and it is not giving me any other option, what should I do?

0 Kudos

422 Views
mehdikarimibiuk
Contributor V

Yes I am using PEE and my bus clock is 50MHz too.

I see you are not using TimeUnit_LDD component. Instead you are using Init_PIT. So using this component, is there no need to initialize it anymore? Also I don't want to toggle the pin all the time. I want to be able to disable/enable the timer when needed throughout my code to be able to toggle the pin whenever needed, is there anyway to do this?

Thanks

Mehdi

0 Kudos