AVRasm2, Low Level INTx is Similar to Falling Edge INTx
Quote from KerimF on January 18, 2024, 11:18 amTrunk versions, Windows 32, ATmega8 MCU
In the register MCUCR (MCU Control Register), setting the two flags ISCx1: ISCx0 to ‘00’ (low level interrupt) acts as ‘10’ (falling edge interrupt).
In other words, if INTx is not enabled and its ISCx1: ISCx0 are set to ‘00’ (low level interrupt mode), its interrupt flag INTFx is set when its interrupt pin (which was high) becomes low (this is expected). But after its INTFx is reset (by setting it to 1) and its interrupt pin is still low, its INTFx is not set again (this is not expected, this is expected in case of falling edge interrupt mode).
Note: This was noticed while debugging a code that uses INT0. So, I assumed that this likely applies on INT1 too.
Trunk versions, Windows 32, ATmega8 MCU
In the register MCUCR (MCU Control Register), setting the two flags ISCx1: ISCx0 to ‘00’ (low level interrupt) acts as ‘10’ (falling edge interrupt).
In other words, if INTx is not enabled and its ISCx1: ISCx0 are set to ‘00’ (low level interrupt mode), its interrupt flag INTFx is set when its interrupt pin (which was high) becomes low (this is expected). But after its INTFx is reset (by setting it to 1) and its interrupt pin is still low, its INTFx is not set again (this is not expected, this is expected in case of falling edge interrupt mode).
Note: This was noticed while debugging a code that uses INT0. So, I assumed that this likely applies on INT1 too.
Quote from arcachofo on January 18, 2024, 11:55 amThanks, I think it is solved at Rev 2167.
But note that the problem happens only if you clear the flag.
If you just leave it alone it should work at expected.
Thanks, I think it is solved at Rev 2167.
But note that the problem happens only if you clear the flag.
If you just leave it alone it should work at expected.
Quote from KerimF on January 18, 2024, 9:54 pmQuote from arcachofo on January 18, 2024, 11:55 amThanks, I think it is solved at Rev 2167.
But note that the problem happens only if you clear the flag.
If you just leave it alone it should work at expected.For instance, if the interrupt service is enabled, the flag is cleared automatically (also by simulIDE), Then, after RETI, it is set again if the interrupt pin is still low (also done by simulIDE).
But if the interrupt service is not enabled, the code just reads the flag (to save time). If it is set, a subroutine is executed, and the flag is cleared. This subroutine has to be executed repeatedly as long the interrupt pin is low only. Therefore, if the flag is not cleared, the code cannot detect when the interrupt pin becomes high in order to stop executing the subroutine (not an interrupt service).
Added:
It happens that the last trunk version by which I can debug my AVRasm2 codes is ‘SimulIDE-R1689_Win32’. But I still use the newer versions to run codes if they have no bugs to fix (in order to take advantage of the simulIDE fast simulation).My question is: Could I fix this bug by editing certain files of ‘SimulIDE-R1689_Win32’?
Thank you.
Quote from arcachofo on January 18, 2024, 11:55 amThanks, I think it is solved at Rev 2167.
But note that the problem happens only if you clear the flag.
If you just leave it alone it should work at expected.
For instance, if the interrupt service is enabled, the flag is cleared automatically (also by simulIDE), Then, after RETI, it is set again if the interrupt pin is still low (also done by simulIDE).
But if the interrupt service is not enabled, the code just reads the flag (to save time). If it is set, a subroutine is executed, and the flag is cleared. This subroutine has to be executed repeatedly as long the interrupt pin is low only. Therefore, if the flag is not cleared, the code cannot detect when the interrupt pin becomes high in order to stop executing the subroutine (not an interrupt service).
Added:
It happens that the last trunk version by which I can debug my AVRasm2 codes is ‘SimulIDE-R1689_Win32’. But I still use the newer versions to run codes if they have no bugs to fix (in order to take advantage of the simulIDE fast simulation).
My question is: Could I fix this bug by editing certain files of ‘SimulIDE-R1689_Win32’?
Thank you.
Quote from arcachofo on January 19, 2024, 1:59 pm
For instance, if the interrupt service is enabled, the flag is cleared automatically (also by simulIDE), Then, after RETI, it is set again if the interrupt pin is still low (also done by simulIDE).
But if the interrupt service is not enabled, the code just reads the flag (to save time). If it is set, a subroutine is executed, and the flag is cleared. This subroutine has to be executed repeatedly as long the interrupt pin is low only. Therefore, if the flag is not cleared, the code cannot detect when the interrupt pin becomes high in order to stop executing the subroutine (not an interrupt service).
I see... then there is no workaround for this issue.
My question is: Could I fix this bug by editing certain files of ‘SimulIDE-R1689_Win32’?
I don't think so, but let me think about it.
For instance, if the interrupt service is enabled, the flag is cleared automatically (also by simulIDE), Then, after RETI, it is set again if the interrupt pin is still low (also done by simulIDE).
But if the interrupt service is not enabled, the code just reads the flag (to save time). If it is set, a subroutine is executed, and the flag is cleared. This subroutine has to be executed repeatedly as long the interrupt pin is low only. Therefore, if the flag is not cleared, the code cannot detect when the interrupt pin becomes high in order to stop executing the subroutine (not an interrupt service).
I see... then there is no workaround for this issue.
My question is: Could I fix this bug by editing certain files of ‘SimulIDE-R1689_Win32’?
I don't think so, but let me think about it.
Quote from KerimF on January 19, 2024, 3:08 pmQuote from arcachofo on January 19, 2024, 1:59 pmI see... then there is no workaround for this issue.
Fortunately, there is a workaround if we use the interrupt pin as an input one.
Instead of monitoring the interrupt flag INTFx, we simply read the status of its pin using PIND (at PD2 or PD3).
I wrote you this to save your time for things more important. You fixed this bug already in the new versions. And, on my side, I can live with it when using my old version.
Best wishes
Kerim
Quote from arcachofo on January 19, 2024, 1:59 pmI see... then there is no workaround for this issue.
Fortunately, there is a workaround if we use the interrupt pin as an input one.
Instead of monitoring the interrupt flag INTFx, we simply read the status of its pin using PIND (at PD2 or PD3).
I wrote you this to save your time for things more important. You fixed this bug already in the new versions. And, on my side, I can live with it when using my old version.
Best wishes
Kerim
Quote from arcachofo on January 19, 2024, 6:13 pmI'm having a look at the datasheet to understand how exactly this interrupt works, when exactly the flag is set/cleared, etc.
I didn't find much, but there is something I don't understand. In the EICRA (or GIFR in Atmega8) register description:• Bit 0 – INTF0: External Interrupt Flag 0
When an edge or logic change on the INT0 pin triggers an interrupt request, INTF0 becomes set
(one). If the I-bit in SREG and the INT0 bit in EIMSK are set (one), the MCU will jump to the cor-
responding Interrupt Vector. The flag is cleared when the interrupt routine is executed.
Alternatively, the flag can be cleared by writing a logical one to it. This flag is always cleared
when INT0 is configured as a level interrupt.What does exactly means that "This flag is always cleared when INT0 is configured as a level interrupt."?
It is never set?
It is always cleared immediately after being set?
It is set and cleared the next cycle?Do you know what is happening in the real device?
I'm having a look at the datasheet to understand how exactly this interrupt works, when exactly the flag is set/cleared, etc.
I didn't find much, but there is something I don't understand. In the EICRA (or GIFR in Atmega8) register description:
• Bit 0 – INTF0: External Interrupt Flag 0
When an edge or logic change on the INT0 pin triggers an interrupt request, INTF0 becomes set
(one). If the I-bit in SREG and the INT0 bit in EIMSK are set (one), the MCU will jump to the cor-
responding Interrupt Vector. The flag is cleared when the interrupt routine is executed.
Alternatively, the flag can be cleared by writing a logical one to it. This flag is always cleared
when INT0 is configured as a level interrupt.
What does exactly means that "This flag is always cleared when INT0 is configured as a level interrupt."?
It is never set?
It is always cleared immediately after being set?
It is set and cleared the next cycle?
Do you know what is happening in the real device?
Quote from KerimF on January 20, 2024, 7:28 amQuote from arcachofo on January 19, 2024, 6:13 pmThis flag is always cleared when INT0 is configured as a level interrupt.
Do you know what is happening in the real device?
You are right, it is confusing. I will have a closer look at it. Thank you.
Quote from arcachofo on January 19, 2024, 6:13 pmThis flag is always cleared when INT0 is configured as a level interrupt.
Do you know what is happening in the real device?
You are right, it is confusing. I will have a closer look at it. Thank you.
Quote from KerimF on January 20, 2024, 8:02 am"This flag is always cleared when INT0 is configured as a level interrupt."
It means actually "This flag is not/never set when INT0 is configured as a level interrupt."
"This flag is always cleared when INT0 is configured as a level interrupt."
It means actually "This flag is not/never set when INT0 is configured as a level interrupt."