📄 evmdm642_osd.c
字号:
/*
* 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.11.00.00 11-04-03 (ddk-b13)" */
/*
* ======== 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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -