Interrupt USB Interrupt?

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

Interrupt USB Interrupt?

1,806 Views
bennxp
Contributor III

I have the MIMXRT1060-EVK and I'm using the code example dev_cdc_vcom_lite_bm for the device to handle USB communications as virtual comm port (CDC device). This works great. The USB interrupts are left at their default priority of 3. I added a new ISR with a priority of 0 that is triggered by an external GPIO signal. I can measure the latency of this interrupt firing and it is typically ~50ns, which is great. However, when I'm sending data of the USB port, this latency can increase to as much as 2us. Why is this? I believe that since my ISR has a higher priority, it can interrupt the USB ISR since the iMX.RT has a nested interrupt controller. I would expect the latency jitter to just be a few ten's of clock cycles  at most depending on what the processor is executing when the interrupt happens and how much stuff it has to push onto the stack. Am I not thinking about this correctly?

The behavior I'm seeing is consistent with the USB ISR having a section of code that disables interrupts for a bit to run some code that cannot get pre-empted. However, I can not find anything like this in the USB code for the CDC_VCOMM_LITE example code I'm using for USB communication.

Below are more details and testing:

If I lower the priority of my interrupt to 4 (lower than USB, which is 3), the latency increases to up to 5us, which makes sense as now my code might have to execute after the USB interrupt.

If I add a delay to the USB ISR this delay greatly increases the latency of my ISR firing when my ISR has a lower priority, however, when run with a higher priority it has no effect. This I believe confirms that the processor is able to jump to my ISR from the USB ISR.

Is there anything the USB code can be doing that would cause the processor to not be able to jump to ISR? I can't find anything disabling interrupts in the USB code, but maybe I missed it somehow. More generally, is there anything the processor could be doing when prevent quick jumping to an interrupt (besides disabling interrupts) -- something that makes it slow to push registers to the stack somehow? Some bus contention when using DMA to transfer data or something?

There relevant configuration of my ISR is:

EnableIRQ(GPIO1_INT3_IRQn);
gpio_pin_config_t sw_config = {kGPIO_DigitalInput,0,kGPIO_IntRisingEdge};
GPIO_PinInit(GPIO1, 3U, &sw_config);
GPIO_PortEnableInterrupts(GPIO1, 1U << 3);
NVIC_SetPriority(GPIO1_INT3_IRQn,0);

Any ideas on what is going on, where to look, how to trouble-shoot appreciated.

Thanks!

Labels (1)
0 Kudos
3 Replies

1,733 Views
jeremyzhou
NXP Employee
NXP Employee

Hi Ben Luey,

Thank you for your interest in NXP Semiconductor products and for the opportunity to serve you.
According to your description, I basically agree with your guess.
To verify it, I'd like t to suggest you to place a breakpoint in the USB interrupt and GPIO interrupt functions respectively, when code runs to these two points, you can observe the global interrupt setting, the priority of above two interrupts, and compare these values from these two time points.
Through the trace way, it can help you to figure this cause out, please give a try.

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

1,734 Views
bennxp
Contributor III

Thanks for your reply. Forgive my ignorance, but how can I get the global interrupt setting? When I debug the code, I can see the register values (and global variables, etc), but I can't find anything about global interrupt settings. Is there a (set of) memory address(es) that I should be probing?

Also, looking at https://community.nxp.com/thread/482121  I wonder if the issue could be bus arbitration delays. Any thoughts on how to test for that?

Thanks,

0 Kudos

1,734 Views
jeremyzhou
NXP Employee
NXP Employee

Hi Ben Luey,

Thanks for your reply.
1) Is there a (set of) memory address(es) that I should be probing?
-- No, it's just Ok to call the function __get_PRIMASK to return the value of PRIMASK register. And this value indicates the global interrupt setting, by the way, this function is defined in cmsis_armcc.h.
__STATIC_INLINE uint32_t __get_PRIMASK(void)
{
register uint32_t __regPriMask __ASM("primask");
return(__regPriMask);
}
2) Any thoughts on how to test for that?
-- In the i.mx rt1050 Interrupt Jitter, NXP co-workers had already shared some suggestions for testing and validation, you can give a try.

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