Interrupts
The FT90x interrupt controller handles 32 interrupt inputs. When an interrupt occurrs, the Interrupt Service Route (ISR) will process this event via the CPU.
The ISR vector range is from 0 to 31, which corresponds to interrupt 0 to 31.
Each interrupt shall be assigned the interrupt vector number and priority before using. By default, the highest priority interrupt is interrupt 0, and the lowest is interrupt 31.
However, the interrupt priority can be rearranged by register settings and also allows multiple interrupts at the same priority.
Nested interrupts are allowed if enabled (by default they are disabled). Up to 16 levels of nesting is allowed which defaults to only 1 level if nesting is enabled.
When nesting is enabled, only interrupts with higher priorities can interrupt the current interrupt. Interrupts of same or lower priorities will be queued as long as the interrupt sources are not cleared.
Peripheral of Interrupt | Interrupt Vector Index | Default Priority |
---|---|---|
Power Management | 0 | 0 (Non-Maskable) |
EHCI Host Controller | 1 | 1 |
USB2.0 Peripheral Controller | 2 | 2 |
Ethernet Controller | 3 | 3 |
SD Host Controller | 4 | 4 |
CAN Bus 0 | 5 | 5 |
CAN Bus 1 | 6 | 6 |
Camera | 7 | 7 |
SPI Master | 8 | 8 |
SPI Slave 0 | 9 | 9 |
SPI Slave 1 | 10 | 10 |
I2C 0 | 11 | 11 |
I2C 1 | 12 | 12 |
UART 0 | 13 | 13 |
UART 1 | 14 | 14 |
I2S Bus | 15 | 15 |
PWM | 16 | 16 |
Timers | 17 | 17 |
GPIO | 18 | 18 |
RTC | 19 | 19 |
ADC | 20 | 20 |
DAC | 21 | 21 |
Slow Clock Timer | 22 | 22 |
UNUSED | 23-31 | 23-31 |
FT90x default interrupt and priority table
Interrupt Service Routine
Interrupt service routine is defined in this way :
sub procedure interrupt() iv IVT_TIMERS_IRQ ics ICS_OFF ' Interrupt service routine code end sub
where :
iv
- reserved word that inform the compiler that it is an interrupt service routine.IVT_TIMERS_IRQ
- appropriate Interrupt Vector.ics
Interrupt Context Saving; Interrupt Context Saving can be performed in several ways :ICS_OFF
- No context savingICS_AUTO
- Compiler chooses whether the context saving will be perfomed or not.
User can explicitly declare starting interrupt routine address using org
directive :
sub procedure Timer0A_interrupt() org 0xC00 iv IVT_INT_TIMER0A ics ICS_OFF ' Interrupt service routine code end sub
Function Calls from Interrupt
Calling functions from within the interrupt routine is possible. The compiler takes care about the registers being used, both in "interrupt" and in "main" thread, and performs "smart" context-switching between two of them, saving only the registers that have been used in both threads. It is not recommended to use a function call from interrupt. In case of doing that take care of stack depth.
Disable Context Saving
Use the DisableContextSaving to instruct the compiler not to automatically perform context-switching.
This means that no register will be saved/restored by the compiler on entrance/exit from interrupt service routine.
This enables the user to manually write code for saving registers upon entrance and to restore them before exit from interrupt.
Interrupt Example
Here is a simple example of handling the interrupts from TimerA
(if no other interrupts are allowed):
program interrupt dim val_ as byte ' Timer interrupt function sub procedure Timer_Interrupt() iv IVT_TIMERS_IRQ ' Toggle led value val_ = not val_ GPIO_PIN60_bit = val_ GPIO_PIN17_bit = val_ ' Clear Timer A interrupt TIMER_INT.B0 = 1 end sub main: ' Initialize LD1 as digital output GPIO_Pin_Digital_Output(_GPIO_PIN_NUM_60) ' Initialize LD2 as digital output GPIO_Pin_Digital_Output(_GPIO_PIN_NUM_17) GPIO_PIN60_bit = 0 GPIO_PIN17_bit = 0 val_ = 0 ' Enable the Timer module TIMER_CONTROL_0 = 2 ' Select Timer A TIMER_SELECT = 0 ' Write prescaler for Timer A 'TIMER_PRESC_LS = 10000 'TIMER_PRESC_MS = 10000 >> 8 ' Write start value 'TIMER_WRITE_LS = 10000 'TIMER_WRITE_MS = 10000 >> 8 ' Set continuous mode and direction down TIMER_CONTROL_3 = 0 ' Trigger clearing timer A and prescaler TIMER_CONTROL_4 = 0x11 ' Enable prescaler for Timer A TIMER_CONTROL_2 = 0x10 ' Enable Timer A interrupt TIMER_INT.B1 = 1 ' Enable global interrupts FT900_INTR_CTRL.B31 = 0 ' Start timer A TIMER_CONTROL_1 = 1 while TRUE wend end.
What do you think about this topic ? Send us feedback!