Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
91 views

Fpga Interrupt

The document discusses interrupts on the MSP430 microcontroller. It explains that interrupts provide a way for the CPU to respond to asynchronous events with low overhead, unlike polling which uses high CPU resources. When an interrupt occurs, the CPU saves its context, determines the interrupt source, clears the interrupt flag, and calls the interrupt service routine (ISR). The ISR saves additional context, handles the interrupt, restores context, and returns from the interrupt. Interrupts have priorities and vector numbers that determine which interrupt is serviced first when multiple occur simultaneously.

Uploaded by

Akhil K R
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
91 views

Fpga Interrupt

The document discusses interrupts on the MSP430 microcontroller. It explains that interrupts provide a way for the CPU to respond to asynchronous events with low overhead, unlike polling which uses high CPU resources. When an interrupt occurs, the CPU saves its context, determines the interrupt source, clears the interrupt flag, and calls the interrupt service routine (ISR). The ISR saves additional context, handles the interrupt, restores context, and returns from the interrupt. Interrupts have priorities and vector numbers that determine which interrupt is serviced first when multiple occur simultaneously.

Uploaded by

Akhil K R
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 22

MSP430 Interrupts

MSP430 Design Workshop


Waiting for an Event: Family Vacation

Polling

An engineering example...
Waiting for an Event: Family Vacation

Polling Interrupts
Wake me up when we get there...

An engineering example...
Waiting for an Event: Button Push

Polling Interrupts
while(1) // Port 1 interrupt service routine
{ #pragma vector=PORT1_VECTOR
if(P1IFG & BIT2) // P1.2 IFG set __interrupt void Port_1(void)
{ {
P1IFG &= ˜BIT2; // P1.2 IFG cleared P1OUT ˆ= BIT0; // Toggle LED at P1.0
P1OUT ˆ= BIT0; // Toggle LED at P1.0 P1IFG &= ˜BIT2; // P1.2 IFG cleared
} }

100% CPU Load > 0.1% CPU Load

How interrupts can affect system design…


How do Interrupts Work?
1. An interrupt occurs
…currently executing code
interrupt occurs
next_line_of_code
• UART
}
• GPIO
• Timers
• ADC
• Etc.
How do Interrupts Work?
1. An interrupt occurs
…currently executing code
interrupt occurs
next_line_of_code
• UART
}
• GPIO
• Timers
• ADC
• Etc.

2. It sets a flag bit


in a register
...

How are interrupts "enabled"?


Interrupt Flow
IFG bit IE bit SR.GIE
Interrupt Interrupt “Individual” “Global”
Source ‘Flag’ Int Enable Int Enable
GPIO 0

TIMER_A 1 CPU
… 0

NMI 0

Global Interrupt Enable (GIE)


Enables ALL maskable interrupts
Enable: __bis_SR_register( GIE );
Disable: __bic_SR_register( GIE );
How do Interrupts Work?
1. An interrupt occurs 3. CPU acknowledges INT by…
• Current instruction completes
…currently executing code • Saves return-to location on stack
interrupt occurs • Saves ‘Status Reg’ (SR) to the stack
next_line_of_code • Clears most of SR, which turns off
• UART interrupts globally (SR.GIE=0)
} • Determines INT source (or group)
• GPIO
• Timers • Clears non-grouped flag* (IFG=0)
• ADC • Reads interrupt vector & calls ISR
• Etc.

2. Sets a flag bit


(IFG) in register
...
How do Interrupts Work?
1. An interrupt 3. CPU acknowledges INT by…
occurs • Current instruction completes
• Saves return-to location on stack
• Saves ‘Status Reg’ (SR) to the stack
• Clears most of SR, which turns off
interrupts globally (SR.GIE=0)
• UART • Determines INT source (or group)
• GPIO • Clears non-grouped flag* (IFG=0)
• Timers • Reads interrupt vector & calls ISR
• A/D Converter
4. ISR (Interrupt Service Routine)
• Etc.
• Save context of system
• (optional) Re-enable interrupts
2. Sets a flag bit • *If group INT, read IV Reg to
(IFG) in register determines source & clear IFG
... • Run your interrupt’s code
• Restore context of system
• Continue where it left off (RETI)
4. Interrupt Service Routine (ISR)

…currently executing code Vector Table


interrupt occurs &myISR
next_line_of_code
}

#pragma vector=WDT_VECTOR
Using Interrupt Keyword interrupt myISR(void){
 Compiler handles context save/restore • Save context of system
 Call a function? Then full context is saved • (optional) Re-enable interrupts
 No arguments, no return values • *If group INT, read assoc IV Reg
(determines source & clears IFG)
 You cannot call any TI-RTOS scheduler
functions (e.g. Swi_post) • Run your interrupt’s code
 Nesting interrupts is MANUAL • Restore context of system
• Continue where it left off (RETI)
}
Interrupt Priorities (F5529)
INT Source Priority
System Reset high  There are 23 interrupts
(partially shown here)
System NMI
User NMI
 If multiple interrupts (of the 23) are
pending, the highest priority is
Comparator responded to first
Timer B (CCIFG0) 0xFFFF
 By default, interrupts are not
Timer B nested …
WDT Interval Timer  That is, unless you re-enable INT’s
Serial Port (A) during your ISR, other interrupts will be
held off until it completes
Serial Port (B)
 It doesn’t matter if the new INT is a
A/D Convertor higher priority
 As already recommended, you should
GPIO (Port 1) keep your ISR’s short
GPIO (Port 2)  Most of these represent ‘groups’ of
Real-Time Clock low interrupt source flags
 145 IFG’s map into these 23 interrupts
Interrupt Vector (IV) Registers
Returns highest
pending Port 1 IFG Port 1 Interrupt Vector Register (P1IV)
 IV = Interrupt Vector register
 Most MSP430 interrupts can be caused by more than one
source; for example:
 Each 8-bi GPIO port one has a single CPU interrupt
 IV registers provide an easy way to determine which
source(s) actually interrupted the CPU
 The interrupt vector register reflects only ‘triggered’
interrupt flags whose interrupt enable bits are also set
 Reading the ‘IV’ register:
 Clears the pending interrupt flag with the highest priority
 Provides an address offset associated with the highest priority
pending interrupt source
Memory Map
Interrupt Vectors & Priorities (F5529)
INT Source IV Register Vector Address Loc’n Priority
System Reset SYSRSTIV RESET_VECTOR 63 high
System NMI SYSSNIV SYSNMI_VECTOR 62 Flash (128K)
User NMI SYSUNIV UNMI_VECTOR 61
Comparator CBIV COMP_B_VECTOR 60
Timer B (CCIFG0) CCIFG0 TIMER0_B0_VECTOR 59 0xFFFF
Timer B TB0IV TIMER0_B1_VECTOR 58 INT Vectors (80)
WDT Interval Timer WDTIFG WDT_VECTOR 57
Serial Port (A) UCA0IV USCI_A0_VECTOR 56 RAM (8K)
Serial Port (B) UCB0IV USCI_B0_VECTOR 55
USB RAM (2K)
A/D Convertor ADC12IV ADC12_VECTOR 54
Info Memory (512)
GPIO (Port 1) P1IV PORT1_VECTOR 47 Boot Loader (2K)

GPIO (Port 2) P12V PORT2_VECTOR 42 Peripherals (4K)


Real-Time Clock RTCIV RTC_VECTOR 41 low

Legend: Non-maskable Group’d IFG bits


Maskable Dedicated IFG bits The 'FR5969 is very similar...
Memory Map
Interrupt Vectors & Priorities (F5529)
INT Source IV Register Vector Address Loc’n Priority
System Reset SYSRSTIV RESET_VECTOR 63 high
System NMI SYSSNIV SYSNMI_VECTOR 62 Flash (128K)
User NMI SYSUNIV UNMI_VECTOR 61
Comparator CBIV COMP_B_VECTOR 60
Timer B (CCIFG0) CCIFG0 TIMER0_B0_VECTOR 59 0xFFFF
Timer B TB0IV TIMER0_B1_VECTOR 58 INT Vectors (80)
WDT Interval Timer WDTIFG WDT_VECTOR 57
Serial Port (A) UCA0IV USCI_A0_VECTOR 56 RAM (8K)
Serial Port (B) UCB0IV USCI_B0_VECTOR 55
USB RAM (2K)
A/D Convertor ADC12IV ADC12_VECTOR 54
Info Memory (512)
GPIO (Port 1) P1IV PORT1_VECTOR 47 Boot Loader (2K)

GPIO (Port 2) P12V PORT2_VECTOR 42 Peripherals (4K)


Real-Time Clock RTCIV RTC_VECTOR 41 low

Legend: Non-maskable Group’d IFG bits Let's look at the ISR for
Maskable Dedicated IFG bits the WDT (dedicated) interrupt...
Interrupt Service Routine (Dedicated INT)
INT Source IV Register Vector Address Loc’n
WDT Interval Timer WDTIFG WDT_VECTOR 57

 #pragma vector assigns


‘myISR’ to correct location
in vector table #pragma vector=WDT_VECTOR
__interrupt void myWdtISR(void) {

GPIO_toggleOutputOnPin( ... );

}
Interrupt Service Routine (Dedicated INT)
INT Source IV Register Vector Address Loc’n
WDT Interval Timer WDTIFG WDT_VECTOR 57

 #pragma vector assigns


‘myISR’ to correct location
in vector table #pragma vector=WDT_VECTOR
__interrupt void myWdtISR(void) {
 __interrupt keyword tells
compiler to save/restore GPIO_toggleOutputOnPin( ... );
context and RETI
}
 For a dedicated
interrupt, the MSP430
CPU auto clears the
WDTIFG flag
Interrupt Service Routine (Group INT)
INT Source IV Register Vector Address Loc’n
GPIO (Port 1) P1IV PORT1_VECTOR 47

 #pragma vector assigns


‘myISR’ to correct location
in vector table #pragma vector=PORT1_VECTOR
__interrupt void myISR(void) {
 __interrupt keyword tells
compiler to save/restore switch(__even_in_range( P1IV, 0x10 )) {
context and RETI case 0x00: break; // None
case 0x02: break; // Pin 0
case 0x04: break; // Pin 1
case 0x06: GPIO_toggleOutputOnPin(…); // Pin 2
break;
case 0x08: break; // Pin 3
case 0x0A: break; // Pin 4
case 0x0C: break; // Pin 5
case 0x0E: break; // Pin 6
case 0x10: break; // Pin 7
default: _never_executed();
}}c
Interrupt Service Routine (Group INT)
INT Source IV Register Vector Address Loc’n
GPIO (Port 1) P1IV PORT1_VECTOR 47

 #pragma vector assigns


‘myISR’ to correct location
in vector table #pragma vector=PORT1_VECTOR
__interrupt void myISR(void) {
 __interrupt keyword tells
compiler to save/restore switch(__even_in_range( P1IV, 0x10 )) {
context and RETI case 0x00: break; // None
case 0x02: break; // Pin 0
 Reading P1IV register: case 0x04: break; // Pin 1
 Returns value for case 0x06: GPIO_toggleOutputOnPin(…); // Pin 2
highest priority INT break;
for the Port 1 ‘group’ case 0x08: break; // Pin 3
 Clears IFG bit case 0x0A: break; // Pin 4
case 0x0C: break; // Pin 5
case 0x0E: break; // Pin 6
case 0x10: break; // Pin 7
default: _never_executed();
}}
Interrupt Service Routine (Group INT)
INT Source IV Register Vector Address Loc’n
GPIO (Port 1) P1IV PORT1_VECTOR 47

 #pragma vector assigns


‘myISR’ to correct location
in vector table #pragma vector=PORT1_VECTOR
__interrupt void myISR(void) {
 __interrupt keyword tells
compiler to save/restore switch(__even_in_range( P1IV, 0x10 )) {
context and RETI case 0x00: break; // None
case 0x02: break; // Pin 0
 Reading P1IV register: case 0x04: break; // Pin 1
 Returns value for case 0x06: GPIO_toggleOutputOnPin(…); // Pin 2
highest priority INT break;
for the Port 1 ‘group’ case 0x08: break; // Pin 3
 Clears IFG bit case 0x0A: break; // Pin 4
case 0x0C: break; // Pin 5
 Tell compiler to ignore case 0x0E: break; // Pin 6
un-needed switch cases case 0x10: break; // Pin 7
by using intrinsics: default: _never_executed();
__even_in_range() }}
_never_executed()
Hardware ISR’s – Coding Practices
 An interrupt routine must be declared with no arguments and must return void
 Global variables are often used to “pass” information to or from an ISR

 Do not call interrupt handling functions directly (Rather, write to IFG bit)
 Interrupts can be handled directly with C/C++ functions using the interrupt
keyword or pragma

 Calling functions in an ISR


 If a C/C++ interrupt routine doesn’t call other functions, usually, only those
registers that the interrupt handler uses are saved and restored.
 However, if a C/C++ interrupt routine does call other functions, the routine saves
all the save-on-call registers if any other functions are called
 Why? The compiler doesn’t know what registers could be used by a nested
function. It’s safer for the compiler to go ahead and save them all.
 Re-enable interrupts? (Nesting ISR’s)
 DON’T – it’s not recommended – better that ISR’s are “lean & mean”
 If you do, change IE masking before re-enabling interrupts
 Disable interrupts before restoring context and returning (RETI re-enables int’s)

 Beware – Only You Can Prevent Reentrancy…


Button Interrupts
 Lab 5a – Pushing your Button
 Create a CCS project that uses an interrupt
to toggle the LED when a button is pushed
 This requires you to create:
o Setup code enabling the GPIO interrupt
o GPIO ISR for pushbutton pin
 You’ll also create code to handle all the
interrupt vectors
Interrupt with Low power
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
P1DIR |= 0x01; // Set P1.0 to output direction
P1IE |= 0x10; // P1.4 interrupt enabled
P1IES |= 0x10; // P1.4 Hi/lo edge
P1IFG &= ~0x10; // P1.4 IFG cleared
_BIS_SR(LPM4_bits + GIE); // Enter LPM4 w/interrupt
}
// Port 1 interrupt service routine
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{
P1OUT ^= 0x01; // P1.0 = toggle
P1IFG &= ~0x10; // P1.4 IFG cleared
}

You might also like