/******************************************************************************/ /* INTR.H - TMS320C6x Peripheral Support Library Interrupt Support */ /* */ /* This file provides the header for the DSP's interrupt support. */ /* */ /* MACRO FUNCTIONS: */ /* INTR_GLOBAL_ENABLE() - Enable global interrupts (GIE) */ /* INTR_GLOBAL_DISABLE()- Disable global interrupts (GIE) */ /* INTR_ENABLE() - Enable interrupt (set bit in IER) */ /* INTR_DISABLE() - Disable interrupt (clear bit in IER) */ /* INTR_CHECK_FLAG() - Check interrupt bit in IFR */ /* INTR_SET_FLAG() - Set interrupt by writing to ISR bit */ /* INTR_CLR_FLAG() - Clear interrupt by writing to ICR bit */ /* INTR_SET_MAP() - Map CPU interrupt to interrupt selector */ /* INTR_GET_ISN() - Get ISN of selected interrupt */ /* INTR_MAP_RESET() - Reset interrupt multiplexer map to defaults */ /* INTR_EXT_POLARITY() - Assign external interrupt's polarity */ /* */ /* FUNCTIONS: */ /* intr_reset() - Reset interrupt registers to default values */ /* intr_init() - Interrupt initialization */ /* intr_isn() - Assign ISN to CPU interrupt */ /* intr_get_cpu_intr() - Return CPU interrupt assigned to ISN */ /* intr_map() - Place ISN in interrupt multiplexer register */ /* */ /* REVISION HISTORY: */ /* */ /* DATE DESCRIPTION */ /* ------- ------------------------------------------------------------- */ /* 02Dec98 Fixed bug in inline intr_map() and intr_isn() functions */ /* that incorrectly used INTSEL_SZ to determine INTSEL bit */ /* offset. INTSEL_SZ is 4, but the fields are actually offset */ /* by 5. Changed "INTSEL_SZ" references to "5" to fix bug. */ /* */ /* 01Jul98 Changed intr_hook() parameter name from "intr_num" to */ /* "cpu_intr" for consistency with other routines' parameters. */ /* */ /* 24Jun98 Changed #define INTR_SET_FLAG(bit) \ */ /* (ISR |= MASK_BIT(bit)) */ /* to #define INTR_SET_FLAG(bit) \ */ /* (ISR = MASK_BIT(bit)) */ /* Changed #define INTR_CLR_FLAG(bit) \ */ /* (ICR |= MASK_BIT(bit)) */ /* to #define INTR_CLR_FLAG(bit) \ */ /* (ICR = MASK_BIT(bit)) */ /* -----> ICR and ISR registers are write only */ /* */ /* 08JUN98 Changed "intr_get_isn" to "intr_isn" in intr_get_cpu_intr(). */ /* */ /* 11MAY98 Changed "#define IMH_RESET_VAL 0x08202d4b" */ /* to "#define IMH_RESET_VAL 0x08202d43" */ /* -----> INTSEL10 incorrectly set */ /* */ /* 11MAY98 Changed INTR_MAP_RESET macro */ /* to #define INTR_MAP_RESET ()\ */ /* { REG_WRITE (INTR_MULTIPLEX_HIGH_ADDR,IMH_RESET_VAL); \ */ /* REG_WRITE (INTR_MULTIPLEX_LOW_ADDR, IML_RESET_VAL);} */ /* -----> Interrupt multiplexer registers improperly reset */ /* */ /* 11MAY98 Added global variables for new interrupt jump table (intr.c): */ /* extern unsigned int NMI, RESV1, RESV2; */ /* extern unsigned int unexp_int04, unexp_int05, unexp_int06;*/ /* extern unsigned int unexp_int07, unexp_int08, unexp_int09;*/ /* extern unsigned int unexp_int10, unexp_int11, unexp_int12;*/ /* extern unsigned int unexp_int13, unexp_int14, unexp_int15;*/ /* -----> Interrupt handling was redone. */ /* */ /* 11MAY98 Changed "CLEAR_BIT(EXTERNAL_INTR_POL_ADDR, bit)" */ /* to "RESET_BIT(EXTERNAL_INTR_POL_ADDR, bit)" */ /* -----> There is no CLEAR_BIT macro */ /* */ /******************************************************************************/ #ifndef _INTR_H_ #define _INTR_H_ #if _INLINE #define __INLINE static inline #else #define __INLINE #endif /*----------------------------------------------------------------------------*/ /* INCLUDES */ /*----------------------------------------------------------------------------*/ #include "regs.h" /*----------------------------------------------------------------------------*/ /* DEFINES AND MACROS */ /*----------------------------------------------------------------------------*/ /******************************************************************************/ /********************** INTERRUPT SELECTOR REGISTERS **************************/ #define INTR_MULTIPLEX_HIGH_ADDR 0x019C0000 #define INTR_MULTIPLEX_LOW_ADDR 0x019C0004 #define EXTERNAL_INTR_POL_ADDR 0x019C0008 #define INTSEL4 0 #define INTSEL_SZ 4 #define INTSEL5 5 #define INTSEL6 10 #define INTSEL7 16 #define INTSEL8 21 #define INTSEL9 26 #define INTSEL10 0 #define INTSEL11 5 #define INTSEL12 10 #define INTSEL13 16 #define INTSEL14 21 #define INTSEL15 26 /* External Interrupt Polarity Register */ #define XIP4 0 #define XIP5 1 #define XIP6 2 #define XIP7 3 /* CPU Interrupt Numbers */ #define CPU_INT_RST 0x00 #define CPU_INT_NMI 0x01 #define CPU_INT_RSV1 0x02 #define CPU_INT_RSV2 0x03 #define CPU_INT4 0x04 #define CPU_INT5 0x05 #define CPU_INT6 0x06 #define CPU_INT7 0x07 #define CPU_INT8 0x08 #define CPU_INT9 0x09 #define CPU_INT10 0x0A #define CPU_INT11 0x0B #define CPU_INT12 0x0C #define CPU_INT13 0x0D #define CPU_INT14 0x0E #define CPU_INT15 0x0F /* Interrupt Selection Numbers */ #define ISN_DSPINT 0x00 #define ISN_TINT0 0x01 #define ISN_TINT1 0x02 #define ISN_SD_INT 0x03 #define ISN_EXT_INT4 0x04 #define ISN_EXT_INT5 0x05 #define ISN_EXT_INT6 0x06 #define ISN_EXT_INT7 0x07 #define ISN_DMA_INT0 0x08 #define ISN_DMA_INT1 0x09 #define ISN_DMA_INT2 0x0A #define ISN_DMA_INT3 0x0B #define ISN_XINT0 0x0C #define ISN_RINT0 0x0D #define ISN_XINT1 0x0E #define ISN_RINT1 0x0F #define IML_SEL 0x00 /* Interrupt Multiplexer Low Select */ #define IMH_SEL 0x01 /* Interrupt Multiplexer High Select */ #define IML_RESET_VAL 0x250718A4 #define IMH_RESET_VAL 0x08202D43 /*----------------------------------------------------------------------------*/ /* MACRO FUNCTIONS */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ /* INTR_GLOBAL_ENABLE - enables all masked interrupts by setting the GIE */ /* bit (bit 0) in the CSR */ /*----------------------------------------------------------------------------*/ #define INTR_GLOBAL_ENABLE() \ SET_REG_BIT(CSR, GIE) /*----------------------------------------------------------------------------*/ /* INTR_GLOBAL_DISABLE - disables all masked interrupts by clearing the GIE */ /* (bit 0) in the CSR. */ /*----------------------------------------------------------------------------*/ #define INTR_GLOBAL_DISABLE() \ RESET_REG_BIT(CSR, GIE) /*----------------------------------------------------------------------------*/ /* INTR_ENABLE - enable interrupt by setting flag in IER */ /*----------------------------------------------------------------------------*/ #define INTR_ENABLE(bit) \ SET_REG_BIT(IER,bit) /*----------------------------------------------------------------------------*/ /* INTR_DISABLE - disable interrupt by clearing flag in IER */ /*----------------------------------------------------------------------------*/ #define INTR_DISABLE(bit) \ RESET_REG_BIT(IER,bit) /*----------------------------------------------------------------------------*/ /* INTR_CHECK_FLAG - checks status of indicated interrupt bit in IFR */ /*----------------------------------------------------------------------------*/ #define INTR_CHECK_FLAG(bit) \ (IFR & MASK_BIT(bit) ? 1 : 0) /*----------------------------------------------------------------------------*/ /* INTR_SET_FLAG - manually sets indicated interrupt by writing to ISR */ /*----------------------------------------------------------------------------*/ #define INTR_SET_FLAG(bit) \ (ISR = MASK_BIT(bit)) /*----------------------------------------------------------------------------*/ /* INTR_CLR_FLAG - manually clears indicated interrupt by writing 1 to ICR */ /*----------------------------------------------------------------------------*/ #define INTR_CLR_FLAG(bit) \ (ICR = MASK_BIT(bit)) /*----------------------------------------------------------------------------*/ /* INTR_SET_MAP - maps a CPU interrupt specified by intr to the interrupt src*/ /* specified by val. Sel is used to select between the low and */ /* high interrupt_multiplexer registers. */ /*----------------------------------------------------------------------------*/ #define INTR_SET_MAP(intsel,val,sel) \ (sel ? LOAD_FIELD(INTR_MULTIPLEX_HIGH_ADDR,val,intsel,INTSEL_SZ) : \ LOAD_FIELD(INTR_MULTIPLEX_LOW_ADDR, val,intsel,INTSEL_SZ )) /*----------------------------------------------------------------------------*/ /* INTR_GET_ISN - returns the ISN value in the selected Interrupt Multiplexer */ /* register for the interrupt selected by intsel */ /*----------------------------------------------------------------------------*/ #define INTR_GET_ISN(intsel,sel) \ (sel ? GET_FIELD(INTR_MULTIPLEX_HIGH_ADDR,intsel,INTSEL_SZ) : \ GET_FIELD(INTR_MULTIPLEX_LOW_ADDR, intsel, INTSEL_SZ)) /*----------------------------------------------------------------------------*/ /* INTR_MAP_RESET - resets the interrupt multiplexer maps to their default val*/ /*----------------------------------------------------------------------------*/ #define INTR_MAP_RESET() \ { REG_WRITE (INTR_MULTIPLEX_HIGH_ADDR,IMH_RESET_VAL); \ REG_WRITE (INTR_MULTIPLEX_LOW_ADDR, IML_RESET_VAL); } /*----------------------------------------------------------------------------*/ /* INTR_EXT_POLARITY - assigns external interrupt external priority. */ /* val = 0 (normal), val = 1 (inverted) */ /*----------------------------------------------------------------------------*/ #define INTR_EXT_POLARITY(bit,val) \ (val ? SET_BIT(EXTERNAL_INTR_POL_ADDR,bit) : \ RESET_BIT(EXTERNAL_INTR_POL_ADDR,bit)) /*----------------------------------------------------------------------------*/ /* GLOBAL VARIABLES */ /*----------------------------------------------------------------------------*/ extern unsigned int istb; extern unsigned int NMI, RESV1, RESV2; extern unsigned int unexp_int04, unexp_int05, unexp_int06, unexp_int07; extern unsigned int unexp_int08, unexp_int09, unexp_int10, unexp_int11; extern unsigned int unexp_int12, unexp_int13, unexp_int14, unexp_int15; /*----------------------------------------------------------------------------*/ /* FUNCTIONS */ /*----------------------------------------------------------------------------*/ extern void interrupt c_int00(void); void intr_reset(void); void intr_init(void); void intr_hook(void (*fp)(void),int cpu_intr); __INLINE void intr_map(int cpu_intr,int isn); __INLINE int intr_isn(int cpu_intr); __INLINE int intr_get_cpu_intr(int isn); #if _INLINE /* intr_map() - Place isn value in Interrupt Multiplexer Register in INTSEL */ /* field indicated by cpu_intr. */ static inline void intr_map(int cpu_intr,int isn) { int intsel; int sel; if (cpu_intr > CPU_INT9) sel=1; else sel= 0; intsel= ((cpu_intr - CPU_INT4) * 5) - (sel * 30); if (intsel > INTSEL6) intsel++; INTR_SET_MAP(intsel,isn,sel); } /* intr_isn() - return isn in interrupt selector corresponding to cpu_intr */ static inline int intr_isn(int cpu_intr) { int intsel; int sel; if (cpu_intr > CPU_INT9) sel= 1; else sel= 0; intsel= ((cpu_intr - CPU_INT4) * 5) - (sel * 30); if (intsel > INTSEL6) intsel++; return(INTR_GET_ISN(intsel,sel)); } /* intr_get_cpu_intr() - return cpu interrupt corresponding to isn in */ /* interrupt selector register. If the isn is not */ /* mapped, return -1 */ static inline int intr_get_cpu_intr(int isn) { int i; for (i= CPU_INT4;i<=CPU_INT15;i++) { if (intr_isn(i) == isn) return(i); } return(-1); } #endif /* _INLINE */ #undef __INLINE #endif /* _INTR_H_ */