Interrupts

SwordfishUser.Interrupts History

Hide minor edits - Show changes to output

Changed line 12 from:
!!! Priortity level is always high when one ISR is defined
to:
!!! Priority level is always high when one ISR is defined
Changed lines 27-28 from:
It's also important to note that even though an interrupt condition was met that fired an interrupt trigger, the 18F will still execute the entire interrupt ISR. So, ensure you define conditional statements in the interrupt that you can tolerate occuring whenever the interrupt is executed. For instance, even though timers, port conditions, etc. may have thier interrupt enable flags off (for example, in the PIEx registers), they may still have the "tripped" flags on (for example, in the PIRx registers).
to:
It's also important to note that even though an interrupt condition was met that fired an interrupt trigger, the 18F will still execute the entire interrupt ISR. So, ensure you define conditional statements in the interrupt that you can tolerate occuring whenever the interrupt is executed. For instance, even though timers, port conditions, etc. may have their interrupt enable flags off (for example, in the PIEx registers), they may still have the "tripped" flags on (for example, in the PIRx registers).
Changed line 32 from:
The use of an "Event" allows the user the flexibility of defining any other action that needs to be done during an interrupt without having to modify an ISR definition that is in a module. This means the module code with the ISR is left untouched so it can be a true generic library to be re-used for different programs. It also provides the benefit that any variables defined in the user's main program can be used in an ISR without having to have them referenced in the ISR's software module. Of course, since events are executed within the context of an ISR, they have to be written to ensure none of the operations would chage any register values that would not be restored at the end of the ISR. In other words, treat then the same as you would when writing the interrupt service routine. This is a real brilliant feature of Swordfish that simplifies ISR module coding.
to:
The use of an "Event" allows the user the flexibility of defining any other action that needs to be done during an interrupt without having to modify an ISR definition that is in a module. This means the module code with the ISR is left untouched so it can be a true generic library to be re-used for different programs. It also provides the benefit that any variables defined in the user's main program can be used in an ISR without having to have them referenced in the ISR's software module. Of course, since events are executed within the context of an ISR, they have to be written to ensure none of the operations would change any register values that would not be restored at the end of the ISR. In other words, treat then the same as you would when writing the interrupt service routine. This is a real brilliant feature of Swordfish that simplifies ISR module coding.
Changed line 19 from:
Users need to heed whether other critical registers are affected in any ISR; for example, if your routine uses any commands that utilize the hardware multiplier, then you should save the PRODL register when you start the ISR and restore it when you leave the ISR.
to:
Users need to heed whether other critical registers are affected in any ISR; for example, if your routine uses any commands that utilize the hardware multiplier, then you should save the PROD registers (PRODL/PRODH) when you start the ISR and restore it when you leave the ISR.
Changed lines 27-28 from:
It's also important to note that even though an interrupt condition was met that fired an interrupt trigger, the 18F will still execute the entire interrupt ISR. So, ensure you only put in functions in the interrupt that you can tolerate occuring whenever the interrupt is executed. For instance, even though timers, port conditions, etc. may have thier interrupt enable flags off (for example, in the PIEx registers), they may still have the "tripped" flags on (for example, in the PIRx registers).
to:
It's also important to note that even though an interrupt condition was met that fired an interrupt trigger, the 18F will still execute the entire interrupt ISR. So, ensure you define conditional statements in the interrupt that you can tolerate occuring whenever the interrupt is executed. For instance, even though timers, port conditions, etc. may have thier interrupt enable flags off (for example, in the PIEx registers), they may still have the "tripped" flags on (for example, in the PIRx registers).
Changed lines 29-30 from:
This means that if a condition such as "if INT0IF = 1 then..." is defined in the ISR, it WILL execute if INT0IF is tripped (a 1 or "true" if defines as a boolean) even if the INT0IE enable bit is "off". Therefore, if you only want some of the parts in the ISR to be executed, you would also have to test for whether the "enable" flags are set (such as in the PIE and some bits in the INTCON registers) as well as just the "tripped" flags (such as in the PIR and some bits in the INTCON registers).
to:
What does this mean? This means conditional statements defined in the ISR testing whether a flag has been being tripped will execute if INT0IF is tripped (a 1 or "true" if defines as a boolean) even if the INT0IE enable bit is "off". For example, an "If INT0IF = 1 then...Endif" conditional statement.  Therefore, if you only want some of the conditional statements in the ISR to be executed, you would also have to test for whether the "enable" flags are set (in the PIE registers and some bits in the INTCON registers) in addition to the "tripped" flags (in the PIR registers and some bits in the INTCON registers).
Changed lines 27-28 from:
It's also important to note that even though an interrupt condition was met that fired an interrupt trigger, the 18F will still execute the entire interrupt ISR. So, ensure you only put in functions in the interrupt that you can tolerate occuring whenever the interrupt is executed. For instance, even though timers, port conditions, etc. may have thier interrupt enable flags off (for example, in the PIEx registers), they may still have the "tripped" flags on (for example, in the PIRx registers). This means that if a condition such as "if INT0IF = 1 then..." is defined in the ISR, it WILL execute if INT0IF is tripped (a 1 or "true" if defines as a boolean) even if the INT0IE enable bit is "off". Therefore, if you only want some of the parts in the ISR to be executed, you would also have to test for whether the "enable" flags are set (such as in the PIE and some bits in the INTCON registers) as well as just the "tripped" flags (such as in the PIR and some bits in the INTCON registers).
to:
It's also important to note that even though an interrupt condition was met that fired an interrupt trigger, the 18F will still execute the entire interrupt ISR. So, ensure you only put in functions in the interrupt that you can tolerate occuring whenever the interrupt is executed. For instance, even though timers, port conditions, etc. may have thier interrupt enable flags off (for example, in the PIEx registers), they may still have the "tripped" flags on (for example, in the PIRx registers).

This means that if a condition such as "if INT0IF = 1 then..." is defined in the ISR, it WILL execute if INT0IF is tripped (a 1 or "true" if defines as a boolean) even if the INT0IE enable bit is "off". Therefore, if you only want some of the parts in the ISR to be executed, you would also have to test for whether the "enable" flags are set (such as in the PIE and some bits in the INTCON registers) as well as just the "tripped" flags (such as in the PIR and some bits in the INTCON registers).
Changed lines 27-28 from:
It's also important to note that even though an interrupt condition was met that fired an interrupt trigger, the 18F will still execute the entire interrupt ISR. So, ensure you only put in functions in the interrupt that you can tolerate occuring whenever the interrupt is executed. For instance, even though timers, port conditions, etc. may have thier interrupt enable flags off (for example, in the PIEx registers), they may still have the "tripped" flags on (for example, in the PIRx registers). This means that if a condition such as "if INT0IF = 1 then..." is defined in the ISR, it WILL execute. Therefore, if you only want some of the parts in the ISR to be executed, you would also have to test for whether the "enable" flags are set (such as in the PIE and some bits in the INTCON registers) as well as just the "tripped" flags (such as in the PIR and some bits in the INTCON registers).
to:
It's also important to note that even though an interrupt condition was met that fired an interrupt trigger, the 18F will still execute the entire interrupt ISR. So, ensure you only put in functions in the interrupt that you can tolerate occuring whenever the interrupt is executed. For instance, even though timers, port conditions, etc. may have thier interrupt enable flags off (for example, in the PIEx registers), they may still have the "tripped" flags on (for example, in the PIRx registers). This means that if a condition such as "if INT0IF = 1 then..." is defined in the ISR, it WILL execute if INT0IF is tripped (a 1 or "true" if defines as a boolean) even if the INT0IE enable bit is "off". Therefore, if you only want some of the parts in the ISR to be executed, you would also have to test for whether the "enable" flags are set (such as in the PIE and some bits in the INTCON registers) as well as just the "tripped" flags (such as in the PIR and some bits in the INTCON registers).
Changed lines 26-28 from:
!!! Execution of low-priority interrupts
It's also important to note that even though a low-priority interrupt condition was met that fired the low-priority
interrupt trigger, the 18F will still execute the high-priority interrupt ISR. So, ensure you only put in functions in the high-priority interrupt that you can tolerate occuring whenever the low-priority interrupt is executed. For instance, even though timers, port conditions, etc. may have thier interrupt enable flags off (for example, in the PIEx registers), they may still have the "tripped" flags on (for example, in the PIRx registers). This means that if a condition such as "if INT0IF = 1 then..." is defined in the high-priority interrupt ISR, it WILL execute.
to:
!!! Execution of conditions in interrupt service routines
It's also important to note that even though an interrupt condition was met that fired an
interrupt trigger, the 18F will still execute the entire interrupt ISR. So, ensure you only put in functions in the interrupt that you can tolerate occuring whenever the interrupt is executed. For instance, even though timers, port conditions, etc. may have thier interrupt enable flags off (for example, in the PIEx registers), they may still have the "tripped" flags on (for example, in the PIRx registers). This means that if a condition such as "if INT0IF = 1 then..." is defined in the ISR, it WILL execute. Therefore, if you only want some of the parts in the ISR to be executed, you would also have to test for whether the "enable" flags are set (such as in the PIE and some bits in the INTCON registers) as well as just the "tripped" flags (such as in the PIR and some bits in the INTCON registers).
Changed lines 3-16 from:
1. Only one high priority and one low priority interrupt service routine (ISR) definition can be compiled in at a time. It's not possible to have, for instance, two high-priority interrupt routines with different names, then enable only one or the other. The way the enable() command works is that it sets the high priority interrupt flag only, not the the interrupt location. The interrupt routine location is only referred to in the interrupt vector at the base of the MPU code, with location 0x08 for high priority and 0x18 for low priority, as defined in the Microchip 18F manuals.

2. You can have both the
ISRs in the main program, one of the ISRs in the main program and one in a module, or both ISRs in one or two modules. You have to define the priority level in the interrupt() routine, including in the respective modules or by the use of an #option statement at the top of the main program that is read by the respective module(s).

3. Resist the temptation to set
the INTCON bits manually. Use the Enable() and Disable() directives instead.

4. Even if only one ISR is defined in the code and is designated as a low priority interrupt, it will be implemented as a high priority interrupt by
the compiler.

5. Only one level of interrupt can be accomodated by the Fast Register Stack built into 18F hardware, where
the STATUS, WREG (W register) and BSR (memory Bank Select Register) are stored until the ISR is complete and returns to normal program execution. When there are two levels of interrupt defined, if a high priority interrupt is called while a low priority interrupt is executing, the STATUS, WREG and BSR are saved again to a software-defined location that is automatically allocated by SF when compiled.

6. Users need to heed whether other critical registers are affected in any ISR; for example, if your routine uses any commands that utilize the hardware multiplier, then you should save
the PRODL register when you start the ISR and restore it when you leave the ISR.

7.
Users need to know that if both a high-priority interrupt and a low-priority interrupt is defined, if the the high-priority interrupt is disabled, the low priority interrupt is also disabled. This is because in the 18F chip, when priority levels are turned on by setting the IPEN bit (bit 7 in the RCON register), disabling the GIE (Global Interrupt Enable) bit (bit 7 of INTCON) all interrupts are disabled. This is an important departure from what you see in other multi-interrupt priority level chips, where each level is enabled/disabled independently.
to:
!!! Defining Interrupt Service Routines (ISRs) using Interrupt()
Only one high priority and one low priority interrupt service routine (ISR) definition can be compiled in at a time. It's not possible to have, for instance
, two high-priority interrupt routines with different names, then enable only one or the other. The way the enable() command works is that it sets the high priority interrupt flag only, not the the interrupt location. The interrupt routine location is only referred to in the interrupt vector at the base of the MPU code, with location 0x08 for high priority and 0x18 for low priority, as defined in the Microchip 18F manuals.

!!! Where
ISRs can be defined
You can have both
the ISRs in the main program, one of the ISRs in the main program and one in a module, or both ISRs in one or two modules. You have to define the priority level in the interrupt() routine, including in the respective modules or by the use of an #option statement at the top of the main program that is read by the respective module(s).

!!! Enabling and disabling ISRs
Resist the temptation to set the INTCON bits manually. Use the Enable() and Disable() directives instead.

!!! Priortity level is always high when one ISR is defined
Even if only one ISR is defined in
the code and is designated as a low priority interrupt, it will be implemented as a high priority interrupt by the compiler.

!!! Context saving on execution of an interrupt routine
Only one level of interrupt can be accomodated by the Fast Register Stack built into 18F hardware, where the STATUS, WREG (W register) and BSR (memory Bank Select Register) are stored until the ISR
is complete and returns to normal program execution. When there are two levels of interrupt defined, if a high priority interrupt is called while a low priority interrupt is executing, the STATUS, WREG and BSR are saved again to a software-defined location that is automatically allocated by SF when compiled.

!!! Ensure all
the registers that will be changed by the ISR are saved
Users need to heed whether other critical registers are affected in any ISR; for example, if your routine uses any commands that utilize the hardware multiplier, then you should save the PRODL register when you start the ISR and restore it when you leave the ISR.

!!! Disabling of high and low priority interrupts

Users need to know that if both a high-priority interrupt and a low-priority interrupt is defined, if the the high-priority interrupt is disabled, the low priority interrupt is also disabled. This is because in the 18F chip, when priority levels are turned on by setting the IPEN bit (bit 7 in the RCON register), disabling the GIE (Global Interrupt Enable) bit (bit 7 of INTCON) all interrupts are disabled. This is an important departure from what you see in other multi-interrupt priority level chips, where each level is enabled/disabled independently.
Changed lines 26-28 from:
8. It's also important to note that even though a low-priority interrupt condition was met that fired the low-priority interrupt trigger, the 18F will still execute the high-priority interrupt ISR. So, ensure you only put in functions in the high-priority interrupt that you can tolerate occuring whenever the low-priority interrupt is executed. For instance, even though timers, port conditions, etc. may have thier interrupt enable flags off (for example, in the PIEx registers), they may still have the "tripped" flags on (for example, in the PIRx registers). This means that if a condition such as "if INT0IF = 1 then..." is defined in the high-priority interrupt ISR, it WILL execute.

9.
The use of an "Event" allows the user the flexibility of defining any other action that needs to be done during an interrupt without having to modify an ISR definition that is in a module. This means the module code with the ISR is left untouched so it can be a true generic library to be re-used for different programs. It also provides the benefit that any variables defined in the user's main program can be used in an ISR without having to have them referenced in the ISR's software module. Of course, since events are executed within the context of an ISR, they have to be written to ensure none of the operations would chage any register values that would not be restored at the end of the ISR. In other words, treat then the same as you would when writing the interrupt service routine. This is a real brilliant feature of Swordfish that simplifies ISR module coding.
to:
!!! Execution of low-priority interrupts
It's also important to note that even though a low-priority interrupt condition was met that fired
the low-priority interrupt trigger, the 18F will still execute the high-priority interrupt ISR. So, ensure you only put in functions in the high-priority interrupt that you can tolerate occuring whenever the low-priority interrupt is executed. For instance, even though timers, port conditions, etc. may have thier interrupt enable flags off (for example, in the PIEx registers), they may still have the "tripped" flags on (for example, in the PIRx registers). This means that if a condition such as "if INT0IF = 1 then..." is defined in the high-priority interrupt ISR, it WILL execute.

!!! Using interrupt "Events" allows for generic ISR modules

The use of an "Event" allows the user the flexibility of defining any other action that needs to be done during an interrupt without having to modify an ISR definition that is in a module. This means the module code with the ISR is left untouched so it can be a true generic library to be re-used for different programs. It also provides the benefit that any variables defined in the user's main program can be used in an ISR without having to have them referenced in the ISR's software module. Of course, since events are executed within the context of an ISR, they have to be written to ensure none of the operations would chage any register values that would not be restored at the end of the ISR. In other words, treat then the same as you would when writing the interrupt service routine. This is a real brilliant feature of Swordfish that simplifies ISR module coding.
Changed line 21 from:
9. The use of an "Event" allows the user the flexibility of defining any other action that needs to be done during an interrupt without having to modify an ISR definition that is in a module. This means the module code with the ISR is left untouched so it can be a true generic library to be re-used for different programs. It also provides the benefit that any variables defined in the user's main program can be used in an ISR without having to have them referenced in the ISR's software module. Of course, since events are executed within the context of an ISR, they have to be written to ensure none of the operations would chage any register values that would not be restored at the end of the ISR. In other words, treat then the same as you would when writing the interrupt service routine.
to:
9. The use of an "Event" allows the user the flexibility of defining any other action that needs to be done during an interrupt without having to modify an ISR definition that is in a module. This means the module code with the ISR is left untouched so it can be a true generic library to be re-used for different programs. It also provides the benefit that any variables defined in the user's main program can be used in an ISR without having to have them referenced in the ISR's software module. Of course, since events are executed within the context of an ISR, they have to be written to ensure none of the operations would chage any register values that would not be restored at the end of the ISR. In other words, treat then the same as you would when writing the interrupt service routine. This is a real brilliant feature of Swordfish that simplifies ISR module coding.
Changed lines 1-2 from:
Here are a few observations when working with a high priority interrupt and a low priority interrupt defined. Maybe with additional input this can become an aide memoire for people implementing multiple interrupts and provide an additional resource for people learning how to get multiple interrupts up and running in Swordfish.
to:
Here are a few observations and tips I have from my experience working with interrupts in Swordfish
Added lines 1-21:
Here are a few observations when working with a high priority interrupt and a low priority interrupt defined. Maybe with additional input this can become an aide memoire for people implementing multiple interrupts and provide an additional resource for people learning how to get multiple interrupts up and running in Swordfish.

1. Only one high priority and one low priority interrupt service routine (ISR) definition can be compiled in at a time. It's not possible to have, for instance, two high-priority interrupt routines with different names, then enable only one or the other. The way the enable() command works is that it sets the high priority interrupt flag only, not the the interrupt location. The interrupt routine location is only referred to in the interrupt vector at the base of the MPU code, with location 0x08 for high priority and 0x18 for low priority, as defined in the Microchip 18F manuals.

2. You can have both the ISRs in the main program, one of the ISRs in the main program and one in a module, or both ISRs in one or two modules. You have to define the priority level in the interrupt() routine, including in the respective modules or by the use of an #option statement at the top of the main program that is read by the respective module(s).

3. Resist the temptation to set the INTCON bits manually. Use the Enable() and Disable() directives instead.

4. Even if only one ISR is defined in the code and is designated as a low priority interrupt, it will be implemented as a high priority interrupt by the compiler.

5. Only one level of interrupt can be accomodated by the Fast Register Stack built into 18F hardware, where the STATUS, WREG (W register) and BSR (memory Bank Select Register) are stored until the ISR is complete and returns to normal program execution. When there are two levels of interrupt defined, if a high priority interrupt is called while a low priority interrupt is executing, the STATUS, WREG and BSR are saved again to a software-defined location that is automatically allocated by SF when compiled.

6. Users need to heed whether other critical registers are affected in any ISR; for example, if your routine uses any commands that utilize the hardware multiplier, then you should save the PRODL register when you start the ISR and restore it when you leave the ISR.

7. Users need to know that if both a high-priority interrupt and a low-priority interrupt is defined, if the the high-priority interrupt is disabled, the low priority interrupt is also disabled. This is because in the 18F chip, when priority levels are turned on by setting the IPEN bit (bit 7 in the RCON register), disabling the GIE (Global Interrupt Enable) bit (bit 7 of INTCON) all interrupts are disabled. This is an important departure from what you see in other multi-interrupt priority level chips, where each level is enabled/disabled independently.

So, it is important to realize that low-priority interrupts only need to be used when you know there is a more important function that has to be addressed immediately, even if it means pre-empting any other operation currently in use. Otherwise, if all functions can wait for the completion of other functions, you might as well put them all into one priority level. Trying to put them into high/low in order to logically organize them doesn't gain you much.

8. It's also important to note that even though a low-priority interrupt condition was met that fired the low-priority interrupt trigger, the 18F will still execute the high-priority interrupt ISR. So, ensure you only put in functions in the high-priority interrupt that you can tolerate occuring whenever the low-priority interrupt is executed. For instance, even though timers, port conditions, etc. may have thier interrupt enable flags off (for example, in the PIEx registers), they may still have the "tripped" flags on (for example, in the PIRx registers). This means that if a condition such as "if INT0IF = 1 then..." is defined in the high-priority interrupt ISR, it WILL execute.

9. The use of an "Event" allows the user the flexibility of defining any other action that needs to be done during an interrupt without having to modify an ISR definition that is in a module. This means the module code with the ISR is left untouched so it can be a true generic library to be re-used for different programs. It also provides the benefit that any variables defined in the user's main program can be used in an ISR without having to have them referenced in the ISR's software module. Of course, since events are executed within the context of an ISR, they have to be written to ensure none of the operations would chage any register values that would not be restored at the end of the ISR. In other words, treat then the same as you would when writing the interrupt service routine.