% #------------------------------------------------------------------------------* # Target specific initializations # build the maps for IRQ # let objForIRQ := @[ ] # Map ISR into objForIRQ foreach isr in ISR do let key := isr::SOURCE if not exists objForIRQ[key] then let objForIRQ[key] := @( ) end if let isr::KIND := "ISR" let objForIRQ[key] += isr end foreach # Map COUNTER into objForIRQ foreach cnt in COUNTER do let key := cnt::SOURCE if not exists objForIRQ[key] then let objForIRQ[key] := @( ) end if let cnt::KIND := "COUNTER" let objForIRQ[key] += cnt end foreach #------------------------------------------------------------------------------* # ISR1 cannot use the same IRQ as ISR2 or COUNTER. # foreach irq in objForIRQ do let objISR1 := @() let objOther := @() # look if the list contains an ISR1 foreach obj in irq do if exists obj::CATEGORY then if obj::CATEGORY == 1 then let objISR1 += obj else let objOther += obj end if end if end foreach if [objISR1 length] > 0 & [objOther length] > 0 then foreach isr1 in objISR1 do error isr1::SOURCE : "Cannot use same IRQ for an ISR1 and an ISR2 or COUNTER" foreach obj in objOther do error obj::SOURCE : "Was used here" end foreach end foreach end if end foreach let INTERRUPTMAP := mapof INTERRUPT by NAME # Build the list of IRQ handlers to call let irqStageList := @( ) # Build a list of virtual objects (sources of interrupts) each of them holding values : # handlerSource, handlerName, handlerAck, generatePrimaryIrq foreach objList in objForIRQ do let anIrq::handlerSource := KEY let anIrq::handlerName := objList[0]::NAME let anIrq::handlerAck := false let anIrq::generatePrimaryIrq := false foreach obj in objList do let anIrq::handlerAck := INTERRUPTMAP[anIrq::handlerSource]::ACK if obj::KIND == "ISR" then if obj::CATEGORY == 1 then let generatePrimaryIrq := true end if end if end foreach let irqStageList += anIrq end foreach #------------------------------------------------------------------------------* %/** * @file tpl_primary_irq.% !EXTENSIONSECONDSTAGE % * * @section descr File description * * Generated from application % !CPUNAME % * Automatically generated by goil on % !TIMESTAMP % * from root OIL file % !OILFILENAME % * * @section infos File informations * * $$Date$$ * $$Rev$$ * $$Author$$ * $$URL$$ */ .syntax unified .thumb #include "tpl_assembler.h" #include "tpl_asm_definitions.h" #include "tpl_os_kernel_stack.h" .equ NO_NEED_SWITCH_NOR_SCHEDULE, 0 .equ NO_NEED_SWITCH, 0 .equ NEED_SWITCH, 1 .equ NEED_SAVE, 2 #define OS_START_SEC_VAR #include "tpl_as_memmap.h" .extern tpl_kern #define OS_STOP_SEC_VAR #include "tpl_as_memmap.h" #define OS_START_SEC_CODE #include "tpl_as_memmap.h" /*============================================================================= * The interrupt handler assumes the following: * * The process stack is populated according to the Cortex M standard * * +------------------+ * | R0 | <- PSP * +------------------+ * | R1 | <- PSP+4 * +------------------+ * | R2 | <- PSP+8 * +------------------+ * | R3 | <- PSP+12 * +------------------+ * | R12 | <- PSP+16 * +------------------+ * | LR | <- PSP+20 * +------------------+ * | Return Address | <- PSP+24 * +------------------+ * | xPSR (bit 9 = 1) | <- PSP+28 * +------------------+ * */ % foreach irq in irqStageList before % % do let handlerSource := irq::handlerSource let handlerName := irq::handlerName let handlerIRQ := handlerSource."_Handler" if not irq::generatePrimaryIrq then % /*============================================================================= * IRQ Handler for IRQ % !handlerName % with source vector % !handlerSource % ******************************************************************************/ % template if exists handler_body end if after % % end foreach % #define OS_STOP_SEC_CODE #include "tpl_as_memmap.h" .end /* End of file tpl_second_stage_irq.% !EXTENSIONSECONDSTAGE % */