evmdm642_osd.c
上传用户:dahaojd
上传日期:2008-01-29
资源大小:14357k
文件大小:4k
- /*
- * Copyright 2003 by Texas Instruments Incorporated.
- * All rights reserved. Property of Texas Instruments Incorporated.
- * Restricted rights to use, duplicate or disclose this code are
- * granted through contract.
- *
- */
- /* "@(#) DDK 1.10.00.23 07-02-03 (ddk-b12)" */
- /*
- * ======== evmdm642_osd.c ========
- * EVMDM642 interrupt handling routines.
- */
- #define CHIP_DM642 1
- #include <std.h>
- #include <atm.h>
- #include <csl.h>
- #include <csl_irq.h>
- #include <evmdm642.h>
- #include <evmdm642_osd.h>
- static Int8 irqMask;
- static struct {
- EVMDM642_OSD_IntHandler func;
- Ptr arg;
- } dispatchTable[EVMDM642_OSD_NUM_IRQ];
- #define CPLDIER *(volatile Uint8 *)(EVMDM642_CPLD_BASE + EVMDM642_IER)
- #define CPLDISR *(volatile Uint8 *)(EVMDM642_CPLD_BASE + EVMDM642_ISR)
- #define CPLDOSDCTRL *(volatile Uint8 *)(EVMDM642_CPLD_BASE + EVMDM642_OSDCTRL)
- static void irqHandler(void);
- /*
- * ======== EVMDM642_OSD_init ========
- * Initialize the CPLD interrupt handling module.
- * Clear all enabled interrupts in the CPLD, add a dispatch
- * handler for EINT7, and enable the interrupt enable line
- * in the OSD control register.
- */
- void EVMDM642_OSD_init()
- {
- int i, gie;
- static int initDone = 0;
- if (!ATM_seti(&initDone, 1)) {
- gie = IRQ_globalDisable();
- irqMask = 0;
- CPLDIER = 0;
- for (i = 0; i < EVMDM642_OSD_NUM_IRQ; i++) {
- dispatchTable[i].func = 0;
- dispatchTable[i].arg = 0;
- }
- HWI_dispatchPlug(IRQ_EVT_EXTINT7, irqHandler, -1, 0);
- IRQ_clear(IRQ_EVT_EXTINT7);
- IRQ_enable(IRQ_EVT_EXTINT7);
- CPLDOSDCTRL |= 0x04;
- IRQ_globalRestore(gie);
- }
- }
- /*
- * ======== EVMDM642_OSD_intHook ========
- * Hook sub-interrupt index on the CPLD interrupt vector. The
- * given function (func) will be called with argument arg when
- * the interrupt becomes active.
- */
- EVMDM642_OSD_IntHandler EVMDM642_OSD_intHook(Uint32 index,
- EVMDM642_OSD_IntHandler func, Ptr arg)
- {
- int gie;
- EVMDM642_OSD_IntHandler oldIsr = (EVMDM642_OSD_IntHandler) NULL;
- if (index < EVMDM642_OSD_NUM_IRQ) {
- gie = IRQ_globalDisable();
- oldIsr = dispatchTable[index].func;
- dispatchTable[index].func = func;
- dispatchTable[index].arg = arg;
- irqMask |= 1 << index;
- CPLDIER = irqMask;
- IRQ_globalRestore(gie);
- }
- return oldIsr;
- }
- /*
- * ======== EVMDM642_OSD_intUnhook ========
- * Unhook sub-interrupt index on the CPLD interrupt vector.
- * This will disable the given sub-interrupt, and zero out
- * the dispatch vector.
- */
- EVMDM642_OSD_IntHandler EVMDM642_OSD_intUnhook(Uint32 index)
- {
- int gie;
- EVMDM642_OSD_IntHandler oldIsr = (EVMDM642_OSD_IntHandler) NULL;
- if (index < EVMDM642_OSD_NUM_IRQ) {
- gie = IRQ_globalDisable();
- irqMask &= ~(1 << index);
- CPLDIER = irqMask;
- oldIsr = dispatchTable[index].func;
- dispatchTable[index].func = 0;
- dispatchTable[index].arg = 0;
- IRQ_globalRestore(gie);
- }
- return oldIsr;
- }
- /*
- * ======== irqHandler ========
- * Local interrupt handler for the CPLD interrupt. Will dispatch
- * all enabled and active interrupts to the appropriate sub-interrupt
- * vector.
- * The global interrupt enable in the OSD control register keeps
- * us from having to cycle on irqFlags != 0. Enabling the global
- * interrupts at the end of the IRQ handler will automatically
- * generate another interrupt if any interrupt bit is still set.
- */
- static void irqHandler(void)
- {
- Uint32 index;
- Int8 irqFlags;
- CPLDOSDCTRL &= ~0x04;
- irqFlags = CPLDISR;
- irqFlags &= irqMask;
- while (irqFlags != 0) {
- index = 31 - _lmbd(1, irqFlags);
- if (dispatchTable[index].func) {
- (*(dispatchTable[index].func))(dispatchTable[index].arg);
- }
- irqFlags &= ~(1 << index);
- }
- CPLDOSDCTRL |= 0x04;
- }