interrupt flag vs interrupt pending bit stm32 - c

I'm using the std library. I don't know what the difference between I2C_FLAG_TXE and I2C_IT_TXE is.
Why when in interrupt function we don't use I2C_ClearFlag instead I2C_ClearITPendingBit? When do we used I2C_ClearFlag?
I'm starting learn stm32f4. I have very little experience.

I'm using the std library. I don't know what the difference between
I2C_FLAG_TXE and I2C_IT_TXE is.
From the processor point of view - the interrupt flag which has to be cleared by interrupt routine is set when the processor enters the interrupt.
Interrupt pending flag - indicates that the event which triggers the interrupt occurred but for some reason the interrupt routine has not been invoked yet.
It is good to know your hardware before using any libraries.

Related

The right way to clear an interrupt flag on STM32

I'm developping a bare-metal project on a STM32L4 and I'm starting from an existing code base.
The ISRs have been implemented the following way:
read interrupt status in the peripheral to know what event(s) provoked the interrupt
do something
clear the flags that have read at the beginning.
Is it the right way to clear the flag ? Shouldn't the flags be cleared at the very beginning of the ISR ? My understanding is that, if the same peripheral event is happening a second time during step 2, it will not provoke a second IRQ so it would be lost. On the other hand if you clear the flag as soon as you can, this second event would pulse the interrupt whose state in the CPU would change to "pending and active": a second IRQ would happen.
PS: From STM32 Processor Programming Manual I read: "STM32 interrupts are both level-sensitive and pulse-sensitive".
Definitely at the beginning (unless you have special reasons in the program logic) as some time is needed the for actual write to the flag clear register to propagate through the buses.
If you decide for some reason to put it at the end of the interrupt you should leave some instructions, place the barrier instruction or read back the register before the interrupt routine return to make sure that the clear operation has propagated across the buses. Otherwise you may have a "phantom" duplicate routine calls.

What happens when a interrupt occurs in RTOS while currently in any task or another ISR?

I have read this question, It is not a valid answer when one interrupt is executing it will not disable all the other interrupts always. It is based on the interrupt type (in some case we need to do manually in our program).
My Question is what happens when a interrupt occurs while executing a
interrupt ??? If Low priority interrupt is executing then High
priority interrupt occurs the what will happen ?
It depends on the system. If the microcontroller/interrupt controller supports nested interrupts and the application enables that feature then a higher priority interrupt will interrupt a lower priority interrupt. In this case the lower priority interrupt will resume when the higher priority interrupt is complete. But if the system does not support nested interrupts then the subsequent interrupt request will pend and be serviced when the active interrupt service routine is complete.
It is too broad for SO, I think and it is arch based.
I try to give you a brief overview, expecting some DV on it. ;)
Mainly, if the arch allow nested interrupts, the interrupt with lower priority is interrupted while executing to jump to the ISR of high level interrupt.
But you can have NMI (Non Maskable Interrupt) that have priority on all other interrupts and cannot be disable.
Usually (all I think) archs have also a global interrupt enable flag, so it must be enabled to allow other interrupts to be served. Also means that an ISR, when is executing, can disable other interrupts during its job.
You can think, for example, on an RTOS implementation: the scheduler can be easily developed using a Timer within its interrupt. This interrupt must have the lower priority and mustn't stops other interrupts (usually): this grant that interrupts are served a soon as possible not considering context switch of RTOS scheduler.
The question was
What happens when a interrupt occurs in RTOS while currently in any task or another ISR?
I have written two commercial RTOS's and there is no answer that satisfies all of the criteria. However, I CAN answer as broadly as the question:
Depending on what is allowed, it will act as a normal interrupt. The problem with this question is that "what happens" is a little broad - some RTOS's do work behind the scenes with interrupts. So, the problem is that the question is not specific enough.
"What happens" in regards to a task is that NOTHING happens in regards to a task. An interrupt is an interrupt and what the relation to a task is depends on the programming. Since I don't read minds, again, the question is not specific enough.
The BEST answer is 42 (HHGTTG)
There is no one answer, sometimes nothing happens the lower prio interrupt continues to completion, sometimes the higher one interrupts the lower. It depends first on the chip/system design, second it depends on the individual programmers across the board RTOS and application folks.
Or another way to say it is, what happens is what those individuals desired to happen in their design and implementation.

Is there a difference between an ISR and an interrupt handler?

I'm studying operating systems and I encountered both the terms ISR and interrupt handler. Are they two words for the same mechanism? If not, what is the difference?
There is no difference in Interrupt handler and ISR.
Wiki says that:
In computer systems programming, an interrupt handler, also known as an interrupt service routine or ISR, is a callback function [...]
ISR is callback for a specific service pertaining to a device/operation/source. There could be multiple ISRs present in a system depending on addresses available in Interrupt Vector table. Where is Interrupt handler is a common routine which is triggered whenever any interrupt comes. Its job is to understand the source of the interrupt and trigger appropriate ISR mapped in Interrupt Vector table.
When interrupt occurs,
interrupt handler performs minimal operations required to respond to the device where as updating the buffer and all other operations are taken care by ISR

whether Single-shot timer stops automatically?

I'm implementing a Timer 1 (which is basically a comparator & capture timer ) in comparator mode with single-shot mode operation? There's an option for starting the timer in continuous mode too.
My question is when I start the timer in single shot mode , after it reaches a mentioned count & compares, it will generate an interrupt flag but then does it mean that the timer is also stopped?
or do I need to stop it explicitly in single -shot mode too? I think it makes sense only in continuous mode?
I'm currently checking only the generated interrupt flag & assuming the timer is stopped & clearing the interrupt flag for further operation & the n come out of my function.
however, there is a control bit in the control register of the timer which can be toggled to make it run or stop? Should I just check the bit after the interrupt flag has generated or do I need to reset this control bit too? Which means I should have an explicit function to stop the timer as well?
Additional Information -
I'm using NXP (Philips ) controller.
Thank you in advance,
Prateek
I just got to read in the NXP datasheet that yes, If any timer, started in single shot (one- shot) mode will stop automatically.
Btw, If any one of you have any explanation kindly, put it below.
Thank you.
To understand microcontroller timers, just have to first realize that there is generally just one single main timer running. When enabled, this timer counts up until it overflows and then starts over.
When you start a "hardware timer", you only set up a register with a timer value which holds the value main_timer + delay. The hardware compares this register with the main timer at every tick, and when they match, it triggers an interrupt, sets a port or whatever you have configured it to do. Typically, you'd have to set up your timer register anew after that.
More more specific answers you have to specify the MCU family and part number used. NXP has made everything from ancient 8051 to modern ARM Cortex, and the timer peripheral hardware will be different for every MCU family.

Cortex: NVIC, please demostrate how to make it level or edge detects by software

I have read the ARM document about Cortex-M3 (or M0) and it say it can be used as level sensetive or pulse (edge) interrupt within the NVIC controller. The problem that it rather vague on how to do this, if this is done by software.
I fails to see any kind of register within the NVIC or such that control the type of the interrupt (to select edge or level by adjusting the register bits). So something must be done by software within handler but again it vague in this field.
I like to hear anyone having a way to make it edge or level trigger interrupt by software.
Please demonstrate within the handler code (if this control it) that the make it detect for level or pulse.
If this is level detect, I can hold interrupt active and disable by the handler, until restore by external code for which it re-excute the interrupt. This is what I'm trying to do, but it will not work if this is pulse detect type.
Thx
A document that describes how the Cortex-M3 NIVC handles level or edge (pulse) triggered interrupts can be found here:
Cortex-M3 Devices Generic User Guide, 4.2.9. Level-sensitive and pulse interrupts
This may well be the document you refer to in your question. Joseph Yiu's book, "The Definitive Guide to the ARM Cortex-M3" also has a pretty good description.
There is no particular configuration of the NVIC for these two interrupt signal types - it handles either kind. Essentially, when an interrupt is asserted (whterh level-based or edge triggered) the NVIC latches that status in the SETPENDx register. When the ISR for that interrupt is vectored to, the corresponding bit in the ACTIVEx register will be set and the bit in the SETPENDx register will be cleared.
While the interrupt is active, if the interrupt line transitions from inactive to active, the pending bit will be turned on again, and upon return from the current active ISR instance, the interrupt will be handled again. This handles the edge triggered interrupt case.
Also, when the ISR returns (and the NVIC clears the 'active' bit), the NIVC will reexamine the state of the interrupt line - if it's still asserted it will set the pending bit again (even if there hasn't been a a transition from inactive to active). This handles the case where an interrupt is level triggered, and the ISR didn't manage to cause the interrupt to be de-asserted (maybe a second device on a shared IRQ line asserted its interrupt at just the critical moment so there was no time when the interrupt line was inactive).
If this is level detect, I can hold interrupt active and disable by the handler, until restore by external code for which it re-execute the interrupt.
I'm not sure I really understand what you're after here, but I think that you might be able to do what you want using the NVIC's SETENAx and CLRENAx registers to enable/disable the interrupt. These work independently of the pending bits, so an interrupt can be pending (or become pending) even if the interrupt is disabled. So you can hold off handling an interrupt for as long as you want.
If that's not quite enough, also note that you can cause an interrupt to pend via software by simply setting the pending bit in the corresponding SETPENDx register - the CPU will vector to the ISR just as if a hardware interrupt were asserted (assuming the interrupt is enabled in the SETENAx register). you can also use the "Software Trigger Interrupt Register" (STIR) to trigger an interrupt by software.

Resources