📄 int.c.svn-base
字号:
/******************************************************************************** **** Copyright (c) 1999 ST Microelectronics **** All rights reserved **** **** Filename : interrupt.c **** Author : Armando Visconti **** Revision : 1.0 **** **** **** *********************************************************************************///#include "stdio.h"#include "vic_pl190.h"#define NULL 0/******************************************************************************************* * * * Here begins the IRQ handlers part * * * ******************************************************************************************/void IRQDefaultHandler(void);/********************************************************************** * eMosaic Interrupt Map Table * * Block Int # Descr * ---------------------------------------------------------- * MAC 0 Level Sensitive - Active HIGH - IRQ (0101) * USB 1 Level Sensitive - Active HIGH - IRQ (0101) * DMA 2 Edge Sensitive - Active LOW - IRQ (0010) * I2C 3 Level Sensitive - Active HIGH - IRQ (0101) * UART 4 Level Sensitive - Active HIGH - IRQ (0101) * RTC 5 Level Sensitive - Active HIGH - IRQ (0101) * Timer 1 6 Level Sensitive - Active LOW - FIQ (1100) * Timer 2 7 Level Sensitive - Active LOW - IRQ (0100) * Ext 1 8 ??? * Ext 2 9 ??? * ---------------------------------------------------------- * * ITC significant bits * * b(3) * 0 ARM IRQ * 1 ARM FIQ * * b(2) b(1) b(0) Purpose * 0 0 0 int_req(i) completely masked. (default) * 0 0 1 int_req(i) is falling edge sensitive. * 0 1 0 int_req(i) is rising edge sensitive. * 0 1 1 int_req(i) is both rising and falling edge sen-sitive. * 1 - 0 int_req(i) is set to be level sensitive, active low. * 1 - 1 int_req(i) is set to be level sensitive, active high. ***********************************************************************//* * Interrupt handler table */static void (*IRQTable[ITC_NUM_INTERRUPTS])(unsigned int) = { (void (*)())NULL, (void (*)())NULL, (void (*)())NULL, (void (*)())NULL, (void (*)())NULL, (void (*)())NULL, (void (*)())NULL, (void (*)())NULL, (void (*)())NULL, (void (*)())NULL, (void (*)())NULL, (void (*)())NULL };/* * This routine initialize the Interrupt Controller. */voidintctlInit(void){ /* * Configure interrupt according to map table. */ IRQCntl->VICIntSelect = 0x000000c0; // all interrupts routed to IRQ (timers to FIQ) IRQCntl->VICDefVectAddr = IRQDefaultHandler; }/* * This routine enable interrupts. */voidintctlIntRegister(unsigned intNum, void (*intHAND)(unsigned int), unsigned char is_vect){ int vector; for (vector = 0; vector < ITC_NUM_INTERRUPTS; vector++) { if (intNum & (1<<vector)) { if (is_vect) { IRQCntl->VICVectAddrs[vector] = intHAND; IRQCntl->VICVectCntl[vector] = 0x20 | vector; } else {IRQTable[vector] = intHAND;} IRQCntl->VICIntEnable |= intNum; } } }/* added by nicola to enhance the IRQ routine */ voidintctlIntRegister_1(unsigned intNum, void (*intHAND)(unsigned int), unsigned char is_vect){ int vector; for (vector = 0; vector < ITC_NUM_INTERRUPTS; vector++) { if (intNum & (1<<vector)) { IRQCntl->VICVectAddrs[is_vect] = intHAND; IRQCntl->VICVectCntl[is_vect] = 0x20 | vector; IRQCntl->VICIntEnable |= intNum; } } }/* * This routine clear interrupts. */voidintctlIntClear(unsigned intNum){}/* * This routine disable interrupts. */voidintctlIntDisable(unsigned intNum){ IRQCntl->VICIntEnClear = intNum;}/* * This routine enable interrupts. */voidintctlIntEnable(unsigned intNum){ IRQCntl->VICIntEnable |= intNum;}//extern void USB_IRQ_Handler(void);extern void AFE_IRQ_Handler(unsigned int);/* * This routine is the General Interrupt Handler. It handles * The IRQ exception and it's called from address 0x18 inside * the VECTOR table. * * It is written in C language using the __irq clause, which tells * the compiler to produce assembly code to store the processor * state. * However, the __irq clause can be used to implement one-level * only interrupt handlers, since it doesn't save all the processor * state required to be re-entrant and to be interrupted itself. * For this reason, the handler leaves ALL interrupts disabled!! * * It simply tests the type of interrupt and calls the right handler. */__attribute__ ((interrupt("IRQ"))) void IRQGeneralHandler(void){ void (*IRQHand)(void) = (void (*)(void))IRQCntl->VICCurrVectAddr; (*IRQHand)(); IRQCntl->VICCurrVectAddr = 0x0;}__attribute__ ((interrupt("FIQ"))) void FIQGeneralHandler(void){ unsigned int fiq = (unsigned int)IRQCntl->VICFIQStatus; int vector; void (*FIQHand)(unsigned int) = 0x0; for (vector = 0; vector < ITC_NUM_INTERRUPTS; vector++) { if (fiq & (1<<vector)) { // Select the right handler for this FIQ FIQHand = IRQTable[vector]; if (FIQHand != 0x0) (*FIQHand)(1<<vector); //intctlIntClear((fiq & (1<<vector))); } }}void IRQDefaultHandler(void){ unsigned int irq = (unsigned int)IRQCntl->VICIRQStatus; int vector; void (*IRQHand)(unsigned int) = 0x0; for (vector = 0; vector < ITC_NUM_INTERRUPTS; vector++) { if (irq & (1<<vector)) { // Select the right handler for this IRQ IRQHand = IRQTable[vector]; if (IRQHand != 0x0) (*IRQHand)(1<<vector); //intctlIntClear((irq & (1<<vector))); } }}#ifdef VIC_TESTunsigned int VicErr = 0;unsigned int addr = 0x00000000;unsigned int i = 0;voidTestVicRegs(void){ /* * VIC Registers Test : check reset values */ if (IRQCntl->VICIRQStatus != 0x00000000) VicErr++; if (IRQCntl->VICFIQStatus != 0x00000000) VicErr++; if (IRQCntl->VICIntSelect != 0x00000000) VicErr++; if (IRQCntl->VICIntEnable != 0x00000000) VicErr++; if (IRQCntl->VICSoftInt != 0x00000000) VicErr++; if ((IRQCntl->VICProtection & VICProtection_MASK) != 0x00000000) VicErr++; if (IRQCntl->VICCurrVectAddr != 0x00000000) VicErr++; if (IRQCntl->VICDefVectAddr != 0x00000000) VicErr++; for (i = 0; i < 16; i++) { if (IRQCntl->VICVectAddrs[i] != 0x00000000) VicErr++; } if ((IRQCntl->VICITOP1 & VICITOP1_MASK) != 0x00000000) VicErr++; if (IRQCntl->VICITOP2 != 0x00000000) VicErr++; if ((IRQCntl->VICPeriphID0 & VICPeriphID_MASK) != 0x00000090) VicErr++; if ((IRQCntl->VICPeriphID1 & VICPeriphID_MASK) != 0x00000011) VicErr++; if ((IRQCntl->VICPeriphID2 & VICPeriphID_MASK) != 0x00000004) VicErr++; if ((IRQCntl->VICPeriphID3 & VICPeriphID_MASK) != 0x00000000) VicErr++; if ((IRQCntl->VICPCellID0 & VICPCellID_MASK) != 0x0000000D) VicErr++; if ((IRQCntl->VICPCellID1 & VICPCellID_MASK) != 0x000000F0) VicErr++; if ((IRQCntl->VICPCellID2 & VICPCellID_MASK) != 0x00000005) VicErr++; if ((IRQCntl->VICPCellID3 & VICPCellID_MASK) != 0x000000B1) VicErr++; /* * VIC Registers Test : Write/Read test */ /* IRQCntl->VICIntSelect = 0x55555555; if (IRQCntl->VICIntSelect != 0x55555555) VicErr++; IRQCntl->VICIntSelect = 0x00000000; if (IRQCntl->VICIntSelect != 0x00000000) VicErr++; */ /* IRQCntl->VICIntEnable = 0xAAAAAAAA; if (IRQCntl->VICIntEnable != 0xAAAAAAAA) VicErr++; IRQCntl->VICIntEnClear = 0xAAAAAAAA; if (IRQCntl->VICIntEnClear != 0xAAAAAAAA) VicErr++; */ /* IRQCntl->VICSoftInt = 0x55555555; if (IRQCntl->VICSoftInt != 0x55555555) VicErr++; IRQCntl->VICSoftInt = 0x00000000; if (IRQCntl->VICSoftInt != 0x00000000) VicErr++; IRQCntl->VICSoftIntClear = 0x55555555; if (IRQCntl->VICSoftInt != 0x00000000) VicErr++; IRQCntl->VICProtection = 0x00000001; if (IRQCntl->VICProtection != 0x00000001) VicErr++; IRQCntl->VICProtection = 0x00000000; if (IRQCntl->VICProtection != 0x00000000) VicErr++; IRQCntl->VICVectAddr = 0x55555555; if (IRQCntl->VICVectAddr != 0x55555555) VicErr++; IRQCntl->VICDefVectAddr = 0xAAAAAAAA; if (IRQCntl->VICDefVectAddr != 0xAAAAAAAA) VicErr++; IRQCntl->VICVectAddr0 = 0x55555555; if (IRQCntl->VICVectAddr0 != 0x55555555) VicErr++; IRQCntl->VICVectAddr15 = 0xAAAAAAAA; if (IRQCntl->VICVectAddr15 != 0xAAAAAAAA) VicErr++; IRQCntl->VICVectCntl0 = 0x55555555; if (IRQCntl->VICVectCntl0 != 0x55555555) VicErr++; IRQCntl->VICVectCntl15 = 0xAAAAAAAA; if (IRQCntl->VICVectCntl15 != 0xAAAAAAAA) VicErr++; IRQCntl->VICITCR = 0x55555555; if (IRQCntl->VICITCR != 0x55555555) VicErr++; */}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -