IMXRT stable microsecond interrupt

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

IMXRT stable microsecond interrupt

2,526 Views
nickwallis
Senior Contributor I

I need a stable microsecond interrupt for some parts of my system.

I tried using timers (PIT and GPT) but what I am finding is there seems to be a surprising amount of jitter (I am toggling a GPIO in the ISR so I can measure on a 'scope).

I am aware that there are internal bus arbitration delays and I have read AN12078.

The timers are running off the perclk which is 75 MHz.

Surely even with these internal delays plus any pad delays, it should be possible to get a clean 1 microsecond interrupt (which after all is only 1 MHz).

Any thoughts on where the jitter might be coming from?

thanks

-Nick

Labels (1)
0 Kudos
12 Replies

2,501 Views
jeremyzhou
NXP Employee
NXP Employee

Hi Nick,

Thank you for your interest in NXP Semiconductor products and for the opportunity to serve you.
Just according to your statement, I'm still not very clear about the 'jitter' you mentioned, so I was wondering if you can introduce your approach to generate the stable interrupt and the 'jitter' behavior on the oscilloscope.
Looking forward to your reply.

Have a great day,
TIC

 

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos

2,459 Views
nickwallis
Senior Contributor I

Hi @jeremyzhou 

Apologies for the delay in replying - please see attached a couple of 'scope grabs which hopefully illustrate what I am referring to. These show a timer interrupt which is setup for 1 microsecond, the GPIO pin is toggled in the ISR (by writing to the DR->TOGGLE register directly). You can see the jitter on the edges, there are 2 plots, one with infinite persist time and the other with 100 ms.

regards

-Nick

 

0 Kudos

2,445 Views
jeremyzhou
NXP Employee
NXP Employee

Thanks for your reply.
I think the jitter phenomenon is related to the configuration of the IOMUXC register, definitely, the environmental condition of the board also affects it.
Next, maybe you can consider setting up other timer modules to output a clean 1 MHz, like TMR.
The below figure demonstrates to output a 1 MHz PWM by running the qtmr_inputcapture_outputpwm demo.

jeremyzhou_0-1603095778898.png

 


Have a great day,
TIC

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos

2,430 Views
nickwallis
Senior Contributor I

Also @jeremyzhou are you saying that the quad timer (TMR) has less jitter than the PIT? Why?

regards Nick

0 Kudos

2,402 Views
jeremyzhou
NXP Employee
NXP Employee

Hi,

Thanks for your reply.

1) Are you saying that the quad timer (TMR) has less jitter than the PIT? Why?
-- No, I consider the jitter phenomenon is related to either the configuration of the IOMUXC register or the environmental condition of the board, of course, the TMR module has particular output pins that make it output PWM that has more high frequency than handling GPIO register.

Have a great day,
TIC

 

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos

2,380 Views
nickwallis
Senior Contributor I

Hi @jeremyzhou 

OK thank you.

The same question as before - Please can you explain, what is it about the configuration of the IOMUXC register that affects jitter? Are you referring to the settings for e.g. speed, drive strength and slew rate?

-Nick

0 Kudos

2,364 Views
jeremyzhou
NXP Employee
NXP Employee

Hi,
Thanks for your reply.
1) What is it about the configuration of the IOMUXC register that affects jitter?
-- In addition to speed, drive strength, slew rate, pull-up/down, the IOMUX option affects the quality of PWM too.
From experience, we usually refer to the configuration that uses in the SDK library.
Have a great day,
TIC

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos

2,433 Views
nickwallis
Senior Contributor I

Hi @jeremyzhou 

Thank you for your reply.

Please can you explain, what is it about the configuration of the IOMUXC register that affects jitter? In the ISR, all I am doing is clearing the interrupt flag, and writing to the DR->TOGGLE register. Why the dependancy on IOMUXC register?

For your other point, yes I am aware that environmental condition (temperature) will change it but for my tests the temperature is not changing, it is stable.

regards Nick

0 Kudos

2,439 Views
mjbcswitzerland
Specialist V

Hi

As noted in my post the PIT trigger can be connected to an output pin as reference for the exact point in time the timer triggered the interrupt.

Regards

Mark

 

2,425 Views
nickwallis
Senior Contributor I

yes @mjbcswitzerland I have seen that, thanks!

I have not experimented with the XBAR yet, but luckily we have a jumper on pin GPIO_AD_B0_04 which can be mux'd to PIT_TRIGGER0, so I might give that a try.

-Nick

0 Kudos

2,417 Views
mjbcswitzerland
Specialist V

Nick

The PIT trigger is simple to view since it is always generated internally and so just needs to be connected to the pin.

I do it like this:

_CONFIG_PERIPHERAL(GPIO_AD_B0_04, PIT_TRIGGER00, (PORT_DSE_MID | PORT_SPEED_MID)); // select PIT_TRIGGER00 on GPIO1-04 - alt function 6

I expect no jitter on this output since it is HW and will be generated even if the processor is in a halted state by the debugger. If you do measure jitter it may question whether the measurement technique is the case so this is an important test.

Assuming that the PIT clock source is synchrnised to the same clock clock source used by the GPIO I also expect no jitter on the interrupt handler toggling a port (just a fixed delay). Should the PIT and GPIO clocks not be synchronised (and the GPIO clock slower) there could be jitter due to the clock domains but at >=75MHz it would probably only be a few ns.

I believe that the GPIOs are clocked by IPG_CLK_ROOT and the PIT from PERCLK_CLK ROOT which would in fact mean that the GPIO clock is either exactly the same as the PIT clock or else it has a higher frequency (synchronised in both cases), which means that the timing accuracy of port writes should be very high.

By the way - do you use the ports in fast mode or slow mode? I used them in slow mode - with added delay - but the delay was stable with no noticeable jitter. I may do some similar measurements in fast mode shortly.

Regards

Mark

 

0 Kudos

2,510 Views
mjbcswitzerland
Specialist V

Nick

Interrupt latency is always 12 cycles for the Cortex-M7

Consider this code:

static __interrupt void _PIT_Interrupt(void)
{
TOGGLE_TEST_OUTPUT();
TOGGLE_TEST_OUTPUT();
__asm("nop");
... 256 times in all
__asm("nop");
TOGGLE_TEST_OUTPUT();
TOGGLE_TEST_OUTPUT();
WRITE_ONE_TO_CLEAR(PIT_TFLG0, PIT_TFLG_TIF); // clear pending interrupts
TOGGLE_TEST_OUTPUT();
TOGGLE_TEST_OUTPUT();
_SYNCHRONISATION_DATA_BARRIER();
TOGGLE_TEST_OUTPUT();
TOGGLE_TEST_OUTPUT();
}

which coverts to assembler as
LDR.N R3, [PC, #0x1fc]
MOVS R2, #8
STR R2, [R3]
STR R2, [R3]
NOP x 256
..
LDR.N R1, [PC, #0x14]
MOVS R0,#1
STR R2, [R3]
STR R2, [R3]
STR R0, [R1]
STR R2, [R3]
STR R2, [R3]
DSB
STR R2, [R3]
STR R2, [R3]
BX LR

Since the PIT can output its trigger on PIT_TRIGGERxx this gives a good method to measure the behavior (600MHz operation with 150MHz IPG and 75MHz PER clock - code and interrupt vectors in ITC):

mjbcswitzerland_1-1601775107385.png

 

A is the PIT_TRIGGERxx output pulse when the PIT fires
A-B is about 65ns
B-C is about 56ns
C-D about 152ns
D-E about 56ns
E-F about 160ns
F-G about 56ns
G-H about 64ns
H to I about 56ns

which gives some interesting insight in to the operation.

First of all it takes about 56ns to toggle an output (maximum toggle rate 18MHz - I have the GPIO in slow mode and not fast mode here) so one can reduce the latency A-B by this value to get the time to enter the interrupt to be about 10ns (even with measurement resolution it is close to the theoretical value).
C-D has 256 nops inserted (each taking 1/2 a clock and so - at 600MHz - 210ns since the Cortex-M7 executes 2 NOPs each cycle (1.2G NOPs /s))
E-F is the first big surprise since the harmless looking STR R0, [R1] takes 160ns to complete (whereby we have already seen that writes to the GPIO takes about 56ns each). This suggests that the write to the PIT's flag register is in fact rather slow (taking as long as about 200 instructions).
Finally note that the DSB adds a delay since it is not allowing the instruction processing to continue until previous data writes have been synchronised (completed). If this is not done the interrupt tends to re-enter as the flag is in fact still pending when the BX LR is executed.

This shows that the instruction processing can be fast - 1.2G instructions per second, but also shows that peripheral accesses can be SLOW and these are not to be underestimated in peripheral interrupts since they can greatly reduce the practical speed that such peripheral interrupts can operate at.

To you question - what can cause jitter?
Firstly the above has no jitter when:
- there is no higher priority interrupt either operating when the PIT trigger or pre-empting it when its starts
- the global interrupts are not masked when the PIT fires

Therefore, to ensure low latency make sure that global interrupts are never masked (use interrupt levels instead as global masking to protect critical regions in code) and give the critical interrupt the highest priority so that it can always pre-empt other interrupts. The worst case would be that it needs to wait for the first interrupt to push its registers before it is taken (2 x normal latency of about 20ns).
Also avoid use of floating point registers in interrupt routines if possible otherwise there is additional FPU register pushing needed.

The above is in idea conditions - no caching needed and zero wait state memory.
Where it can go quite horribly wrong is when:
1- Interrupt vectors are not stored in ITC but in a different memory. Then that memory's wait states kick in and the latency multiplies.
2. The stack in not in DTC and so each register push takes longer due to that memory's speed.
3- Interrupt vectors are in QSPI flash - if they are in cache it is fast (same as in ITC) but if they are not a QSPI flash read bust is needed to load them and BIG additional delays can result.
4 - same for the interrupt routine itself. If it is not in ITC it will be fast if it happens to be in cache but each time it is kicked out of cache due to other code being loaded it has to be re-fetched and thus BIG potential jitter.

General note: a lot of peripherals have internal triggers (generating DMA or interrupts) that can be connected to XBAR outputs for visibility on pin outputs (see https://www.youtube.com/watch?v=zNWIG-O7ZW0&list=PLWKlVb_MqDQEOCnsNOJO8gd3jDCwiyKKe&index=6). These are useful for timing measurements since the REAL interrupt reference in time is visible/measurable. Just measuring GPIOs in the interrupt itself will miss delays due to waiting for other interrupts and such.

 

Regards

Mark
[uTasker project developer for Kinetis and i.MX RT]
Contact me by personal message or on the uTasker web site to discuss professional training or product development requirements