Configuring the clock for PIT

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

Configuring the clock for PIT

Jump to solution
2,251 Views
yvesb
Contributor II

Hi,

I'm still discovering the K20 chip using the Tower K20 demo kit with the demo_gpio project supplied by freescale.

I have set a PIT as described in this earlier topic: https://community.freescale.com/thread/320172

I've left all the MCG config as is in the demo project.

the maximum tick frequency I can get with the PIT is around 2MHz, although the mcg_clk_hz is 72.000.000 (= core_clk)

Is this normal? I thought the max freq achievable with PIT should be half the core clock.

regards,

Yves B

Labels (1)
0 Kudos
1 Solution
1,219 Views
mjbcswitzerland
Specialist V

Yves

Maybe you have the bus divider set to 1 and not 2? This would be exceeding the bus clock specification but it probably still works under most conditions (over-clocking).

Since your IRQ is presently toggling at 2MHz it is capable of measuring a timer periodicity of 250ns (assuming no other interrupt or code are executed).

Regards

Mark

View solution in original post

0 Kudos
4 Replies
1,219 Views
mjbcswitzerland
Specialist V

Yves

Your results are about what is to be expected since you are measuring the interrupt handling speed and not directly the PIT speed. The PIT will be faster than your interrupt can handle it.

Ex. PIT 1 on K20F120 at 120MHz (bus clock 60MHz). Code runnig from RAM and PIT period set to minimum (value 0 in PIT_LDVAL).

static __interrupt void _PIT1_Interrupt(void)

{

    PIT_TFLG1 = PIT_TFLG_TIF;                                            // clear pending interrupts

    _TOGGLE_PORT(D, DEMO_LED_2);

}

This toggles at about 2.8MHz

The following code, which allows the user to specify a call-back doing the same (and controls periodic or single-shot mode of operation)

static __interrupt void _PIT1_Interrupt(void)

{

    PIT_TFLG1 = PIT_TFLG_TIF;                                            // clear pending interrupts

    if (!(ucPITmodes & (PIT_PERIODIC << 2))) {                           // if not periodic mode

        fnDisablePIT(1);                                                 // stop PIT operation and power down when no other activity

    }

    uDisable_Interrupt();

    pit_interrupt_handler[1]();                                          // call handling function

    uEnable_Interrupt();

}

// User code toggling the LED

static void pit_call_back(void)

{

    _TOGGLE_PORT(D, DEMO_LED_2);

}


causes the LED to toggle at about 1MHz instead. This is due to the additional code that needs to be executed in each interrupt.

This shows that, when running at 72MHz (assuming no Flash wait states) the Cortex M4 has an instruction rate of 72 per us. The most efficient interrupt handling to toggle an LED and reset the PIT flag therefore requires about 18 instructions (including collecting the interrupt vector, jumping to it, pushing and popping context etc.).

If you want to measure the speed that the PIT is running at you need to (for example) allow it to count freely and read it at 1s intervals. Assuming it is running at bus speed (36MHz in your case) and you read PIT 1 you will see that the value in PIT_CVAL1 decreases by 36000000 (0x2255100) each second. If you set an interrupt only when it counts from 0xffffffff to 0 it will fire after 119.3s. Therefore to measure the PIT speed (and confirm that it is running at the bus speed) you can easily measure it indirectly rather than have the interrupt handling speed distorting the value (note that to be able to measure 36MHz interrupt rates the processor would need to be able to execute the complete interrupt in a single processor clock cycle - single instruction. Alternatively, a faster processor could just do it if it were clocked at aroung 1.5GHz and could execute the instructions in memory that could also work at that speed)

Regards

Mark

0 Kudos
1,219 Views
yvesb
Contributor II

actually, if I set the load value to 36.000.000 I get an interrupt every 500ms.

the aim of my test here is to find the smallest time between 2 interrupts I could accurately measure using the K20.

If I understand correctly, with any timer, I couldn't measure a time lower than 500ns?

(for example measure time between the rising edges of two different inputs to know the latency)

0 Kudos
1,220 Views
mjbcswitzerland
Specialist V

Yves

Maybe you have the bus divider set to 1 and not 2? This would be exceeding the bus clock specification but it probably still works under most conditions (over-clocking).

Since your IRQ is presently toggling at 2MHz it is capable of measuring a timer periodicity of 250ns (assuming no other interrupt or code are executed).

Regards

Mark

0 Kudos
1,219 Views
yvesb
Contributor II

Thanks Mark :smileyhappy:

0 Kudos