evmdm642_osd.c
上传用户:dahaojd
上传日期:2008-01-29
资源大小:14357k
文件大小:4k
源码类别:

DSP编程

开发平台:

C/C++

  1. /*
  2.  *  Copyright 2003 by Texas Instruments Incorporated.
  3.  *  All rights reserved. Property of Texas Instruments Incorporated.
  4.  *  Restricted rights to use, duplicate or disclose this code are
  5.  *  granted through contract.
  6.  *  
  7.  */
  8. /* "@(#) DDK 1.11.00.00 11-04-03 (ddk-b13)" */
  9. /*
  10.  *  ======== evmdm642_osd.c ========
  11.  *  EVMDM642 interrupt handling routines.
  12.  */
  13. #define CHIP_DM642      1
  14. #include <std.h>
  15. #include <atm.h>
  16. #include <csl.h>
  17. #include <csl_irq.h>
  18. #include <evmdm642.h>
  19. #include <evmdm642_osd.h>
  20. static Int8 irqMask;
  21. static struct {
  22.     EVMDM642_OSD_IntHandler func;
  23.     Ptr arg;
  24. } dispatchTable[EVMDM642_OSD_NUM_IRQ];
  25. #define CPLDIER     *(volatile Uint8 *)(EVMDM642_CPLD_BASE + EVMDM642_IER)
  26. #define CPLDISR     *(volatile Uint8 *)(EVMDM642_CPLD_BASE + EVMDM642_ISR)
  27. #define CPLDOSDCTRL *(volatile Uint8 *)(EVMDM642_CPLD_BASE + EVMDM642_OSDCTRL)
  28. static void irqHandler(void);
  29. /*
  30.  *  ======== EVMDM642_OSD_init ========
  31.  * Initialize the CPLD interrupt handling module.
  32.  * Clear all enabled interrupts in the CPLD, add a dispatch
  33.  * handler for EINT7, and enable the interrupt enable line
  34.  * in the OSD control register.
  35.  */
  36. void EVMDM642_OSD_init()
  37. {
  38.     int i, gie;
  39.     static int initDone = 0;
  40.     if (!ATM_seti(&initDone, 1)) {
  41.         gie = IRQ_globalDisable();
  42.         irqMask = 0;
  43.         CPLDIER = 0;
  44.         for (i = 0; i < EVMDM642_OSD_NUM_IRQ; i++) {
  45.             dispatchTable[i].func = 0;
  46.             dispatchTable[i].arg = 0;
  47.         }
  48.         HWI_dispatchPlug(IRQ_EVT_EXTINT7, irqHandler, -1, 0);
  49.         IRQ_clear(IRQ_EVT_EXTINT7);
  50.         IRQ_enable(IRQ_EVT_EXTINT7);
  51.         CPLDOSDCTRL |= 0x04;
  52.         IRQ_globalRestore(gie);
  53.     }
  54. }
  55. /*
  56.  *  ======== EVMDM642_OSD_intHook ========
  57.  * Hook sub-interrupt index on the CPLD interrupt vector.  The
  58.  * given function (func) will be called with argument arg when
  59.  * the interrupt becomes active.
  60.  */
  61. EVMDM642_OSD_IntHandler EVMDM642_OSD_intHook(Uint32 index,
  62.         EVMDM642_OSD_IntHandler func, Ptr arg)
  63. {
  64.     int gie;
  65.     EVMDM642_OSD_IntHandler oldIsr = (EVMDM642_OSD_IntHandler) NULL;
  66.     if (index < EVMDM642_OSD_NUM_IRQ) {
  67.         gie = IRQ_globalDisable();
  68.         oldIsr = dispatchTable[index].func;
  69.         dispatchTable[index].func = func;
  70.         dispatchTable[index].arg = arg;
  71.         irqMask |= 1 << index;
  72.         CPLDIER = irqMask;
  73.         IRQ_globalRestore(gie);
  74.     }
  75.     return oldIsr;
  76. }
  77. /*
  78.  *  ======== EVMDM642_OSD_intUnhook ========
  79.  * Unhook sub-interrupt index on the CPLD interrupt vector.
  80.  * This will disable the given sub-interrupt, and zero out
  81.  * the dispatch vector.
  82.  */
  83. EVMDM642_OSD_IntHandler EVMDM642_OSD_intUnhook(Uint32 index)
  84. {
  85.     int gie;
  86.     EVMDM642_OSD_IntHandler oldIsr = (EVMDM642_OSD_IntHandler) NULL;
  87.     if (index < EVMDM642_OSD_NUM_IRQ) {
  88.         gie = IRQ_globalDisable();
  89.         irqMask &= ~(1 << index);
  90.         CPLDIER = irqMask;
  91.         oldIsr = dispatchTable[index].func;
  92.         dispatchTable[index].func = 0;
  93.         dispatchTable[index].arg = 0;
  94.         IRQ_globalRestore(gie);
  95.     }
  96.     return oldIsr;
  97. }
  98. /*
  99.  *  ======== irqHandler ========
  100.  * Local interrupt handler for the CPLD interrupt.  Will dispatch
  101.  * all enabled and active interrupts to the appropriate sub-interrupt
  102.  * vector.
  103.  * The global interrupt enable in the OSD control register keeps
  104.  * us from having to cycle on irqFlags != 0.  Enabling the global
  105.  * interrupts at the end of the IRQ handler will automatically
  106.  * generate another interrupt if any interrupt bit is still set.
  107.  */
  108. static void irqHandler(void)
  109. {
  110.     Uint32 index;
  111.     Int8 irqFlags;
  112.     CPLDOSDCTRL &= ~0x04;
  113.     irqFlags = CPLDISR;
  114.     irqFlags &= irqMask;
  115.     while (irqFlags != 0) {
  116.         index = 31 - _lmbd(1, irqFlags);
  117.         if (dispatchTable[index].func) {
  118.             (*(dispatchTable[index].func))(dispatchTable[index].arg);
  119.         }
  120.         irqFlags &= ~(1 << index);
  121.     }
  122.     CPLDOSDCTRL |= 0x04;
  123. }