Exception and Interrupt handlers

The file Cortex\IntCortex.fth contains generic interrupt handlers for Cortex-M0/M1/M3/M4 processors. IntCortex.fth requires Cortex\CortexDef to be compiled before the SFRxxxx file for your particular CPU. The file Cortex/StackDef.fth provides default main task and stack layouts and should be compiled from the control file or copied into your control file. Default stack initialisation code is provided in Cortex/StackDef.fth.

The high-level interrupt handlers all share a common "stack of stacks". On entry to the interrupt handler, Forth system registers are allocated. Your initialisation code must set up R13. This is normally provided by the MPE wrapper code for each exception.

In order to support exception nesting the equate #IRQs in the control file must be set to the maximum number of nestings required. The equate #IRQs is used to calculate the size of the required exception stack, together with the equate #SVCs. in the control file.

Each interrupt has its own USER area. No user variables are initialised except for S0 and R0 in SVC handlers.

It is assumed that the banked stack pointers have already been set up by the hardware initialisation code.

It is implicit throughout the code that the system registers UP, PSP, FSP, RSP are always set so that:

  UP > PSP > FSP > RSP

Because of this layout, data stack underflows may corrupt the first part of the USER area. You have been warned. During testing, it may be as well to set the equate SP-GUARD to 2 or 3 in your control file to leave a few guard cells on the data stack.

Cortex-M3 NVIC Exception handlers

This section is not a treatise on the Nested Vectored Interrupt Controller. These words provide a fairly basic set of tools for using the NVIC, which is fully documented in the Cortex-M3 Technical Reference Manual (ARM DDI 0337)from www.arm.com.

This code requires Kernel62.fth and the equate COLDCHAIN? must be set non-zero in the control file. The NVIC address and register offsets are defined in the file Cortex/CortexDef.fth.

The MPE code works in terms of vector numbers, which are 16 greater than the external interrupt numbers.

PROC ExcEntry   \ --
This is the template code for M3+ vectored exception handlers.

SP-SIZE #256 u< 0=  UP-SIZE #256 u< 0= or  equ LargeISR?  \ -- flag
The interrupt is often larger than 256 bytes, which requires larger ISR entry code.

PROC ExcEntry   \ --
This is the template code for M0/M1 vectored exception handlers with a large ISR frame.

PROC ExcEntry   \ --
This is the template code for M0/M1 vectored exception handlers with a small ISR frame. A separate floating point stack is not currently supported in interrupts.

: EXC:          \ xt vec# -- ; -- isr
Creates an exception handler that runs the given Forth word. At run time the entry point of the ISR is returned. Use in the form:

  ' <action> <vec#> EXC: <actionISR>

The example below will define a handler for the SysTick interrupt/exception that runs the Forth word SysTickHandler.

  ' SysTickHandler #15 EXC: SysTickEntry

: EnInt         \ vec# --
Enable the requested NVIC interrupt source. NVIC interrupts have vector numbers in the range 16..255.

: DisInt        \ vec# --
Disable the requested NVIC interrupt source. NVIC interrupts have vector numbers in the range 16..255.

: SetPri        \ pri vec# --
Set the priority of the given NVIC interrupt source. NVIC interrupts have vector numbers in the range 16..255. The priority numbers are in the range 0..255, where 0 is the highest priority. The number of bits actually used is implementation dependent, but unused bits are always the low-order bits. Hence, using $10, $20 and so on is fairly portable.

: SWINT         \ vec# --
Generate interrupt from software.