cancel
Showing results for 
Search instead for 
Did you mean: 

Nested interrupts STM32L4

dpn
Associate II

Hello,

I have an interrupt driven I2C which is working fine.

I know that this is not very clean design but I need to execute few I2C transactions from a button interrupt handler (EXTI9_5_IRQn).

I have set the priority of the EXTI9_5_IRQn 1 and the priority of my I2C3_EV_IRQn to 0 but I can not make my I2C working.

I saw people talking about preemption grouping. Can someone clarify or point me to an example?

Thank you in advance

Dimitar

6 REPLIES 6
Piranha
Chief II

Custom code, HAL or what? Interrupts, DMA, polling? Does it work outside the interrupt context?

dpn
Associate II

Hi Piranha,

I am using  Low Layer LL layer.

Yes as I have stated my I2C communication is working fine outside the interrupt context.

Due to some other reasons (which I don't want to go in details here) I would like to make it working from a button interrupt handler.

Thank you

Dimitar

Seem to recall Joseph Yiu's books cover the bit allocations for preemption and priority on the NVIC side

More generally I think there are a couple of issues, how the SysTick and I2C interrupts coexist with the EXTI one, and how you arbitrate ownership of the I2C.

You really don't want the EXTI to plough into the middle of an ongoing I2C transaction. Both foreground and background should attempt to take a mutex/ownership of the resource. The foreground is unlikely to fail unless you've created a deadlock or resource leak, but on release it can defer to a pending EXTI initiated request. If the EXTI can't take ownership, it should flag some deferred action and leave immediately. Break the action into it's own routine so the foreground can do a call-back prior to releasing the resource.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

> I know that this is not very clean design

Why would that be not clean?

> I saw people talking about preemption grouping. Can someone clarify or point me to an example?

Preemption is ARM's lingo for interrupts nesting. The number you set as priority is in fact split (i.e. some bits of it go into one part, the rest into the other part) into two parts: one determines ability to nest, the other determines which one of pending interrupts of the same "nesting" priority is executed as first (this is "interrupts polling" in Intel lingo). As a very interesting but maybe not that well thought out feature, in Cortex-M the number of bits which goes into either group, is settable...and by default, all bits go into the "polling" priority, i.e. whatever priority you set, it just determines the "polling" order and by default interrupts can't nest. [EDIT] read Piranha's post below [/EDIT]

For the boring details, see either ARM's documents, or PM0214, PRIGROUP field in AIRCR register and the subsequent Binary point subchapter.

NVIC_SetPriorityGrouping(3); // #define NVIC_PRIORITYGROUP_4         0x00000003U /* 4 bits for pre-emption priority 0 bits for subpriority */

JW

> by default, all bits go into the "polling" priority, i.e. whatever priority you set, it just determines the "polling" order and by default interrupts can't nest.

It's the other way around. By default PRIGROUP field value is 0 and, as STM32 has 4 priority bits, all values in a range 0..3 make 16 group priorities and 0 subpriorities. PM0214 table 51 also confirms this. It's just that value 0 is universal "all bits to group priorities" for all Cortex-M implementations and one doesn't have to write unnecessary code. 🙂

For anyone interested in details:

https://community.arm.com/developer/ip-products/system/b/embedded-blog/posts/cutting-through-the-confusion-with-arm-cortex-m-interrupt-priorities

"In most applications, I would highly recommended to assign all the interrupt priority bits to the preempt priority group, leaving no priority bits as subpriority bits, which is the default setting out of reset. Any other configuration complicates the otherwise direct relationship between the interrupt priority number and interrupt urgency.

NOTE: Some third-party code libraries (e.g., the STM32 driver library) change the priority grouping configuration to non-standard. Therefore, it is highly recommended to explicitly re-set the priority grouping to the default by calling the CMSIS function NVIC_SetPriorityGrouping(0U) after initializing such external libraries."

Also everyone loves the ST's talented HAL team... 🙂

I stand corrected. Thanks, Piranha, for the details and the excellent link.

JW