s3c2410xIntrCtl__.c
上传用户:ske666
上传日期:2022-03-30
资源大小:371k
文件大小:6k
源码类别:

VxWorks

开发平台:

Objective-C

  1. /* s3c2410xIntrCtl.c - s3c2410x interrupt controller driver */
  2. /* Copyright 2004, HITSAT, Inc. */
  3. #include "vxWorks.h"
  4. #include "config.h"
  5. IMPORT FUNCPTR sysIntLvlVecChkRtn;
  6. IMPORT FUNCPTR sysIntLvlEnableRtn;
  7. IMPORT FUNCPTR sysIntLvlDisableRtn;
  8. /* hardware access methods */
  9. #ifndef s3c2410x_INT_REG_READ
  10. #define s3c2410x_INT_REG_READ(reg,result) 
  11. ((result) = *(volatile UINT32 *)(reg))
  12. #endif
  13. #ifndef s3c2410x_INT_REG_WRITE
  14. #define s3c2410x_INT_REG_WRITE(reg,data) 
  15. (*((volatile UINT32 *)(reg)) = (data))
  16. #endif
  17. /* Local data 
  18. #define s3c2410x_INT_ALL_ENABLED (s3c2410x_INT_NUM_LEVELS)
  19. #define s3c2410x_INT_ALL_DISABLED (s3c2410x_INT_NUM_LEVELS-1)
  20. */
  21. /* Current interrupt level setting (s3c2410xIntLvlChg). */
  22. /*LOCAL UINT32 s3c2410xIntLvlCurrent = s3c2410x_INT_ALL_DISABLED;  all levels disabled */
  23. /* 
  24.  * A mask word.  Bits are set in this word when a specific level
  25.  * is enabled. It is used to mask off individual levels that have
  26.  * not been explicitly enabled.
  27.  */
  28. LOCAL UINT32 s3c2410xIntLvlEnabled;
  29. /* forward declarations */
  30. STATUS s3c2410xIntLvlVecChk (int*, int*);
  31. STATUS s3c2410xIntLvlEnable (int);
  32. STATUS s3c2410xIntLvlDisable (int);
  33. /*
  34.  * s3c2410xIntDevInit - initialize the interrupt controller
  35.  *
  36.  * This routine will:
  37.  * <1> Initialize the interrupt controller device;
  38.  * <2> Disabling all interrupt sources;
  39.  * <3> Connect the device driver specific routines into the architecture level hooks.
  40.  *
  41.  * If the BSP needs to create a wrapper routine around any of the arhitecture level routines,
  42.  * it should install the pointer to the wrapper routine after calling this routine.
  43.  * 
  44.  * RETURNS: N/A.
  45.  */
  46. int s3c2410xIntDevInit (void)
  47. {
  48. UINT32 tempUINT32 = 0;
  49. /* <1> Initialize the interrupt controller device; */
  50. s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTMSK,0xfeffffbf); /* Mask all Interrupt. */
  51. s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTSUBMSK,0x7ff); /* Mask all subInterrupt. */
  52. s3c2410x_INT_REG_READ(s3c2410x_INT_CSR_SUBSRCPND,tempUINT32);
  53. s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_SUBSRCPND,tempUINT32); /* Clear SUBSRCPND */
  54. s3c2410x_INT_REG_READ(s3c2410x_INT_CSR_SRCPND,tempUINT32);
  55. s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_SRCPND,tempUINT32); /* Clear SRCPND */
  56. s3c2410x_INT_REG_READ(s3c2410x_INT_CSR_INTPND,tempUINT32);
  57. s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTPND,tempUINT32); /* Clear INTPND. */
  58. s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTMOD,0); /* Select IRQ mode. */
  59. s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_PRIORITY,0); /* Set priority. */
  60. s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_EINTSTYLE,EINT0_7_STYLE);
  61. /* <3> Install the driver routines in the architecture hooks */
  62. sysIntLvlVecChkRtn = s3c2410xIntLvlVecChk;
  63. sysIntLvlEnableRtn = s3c2410xIntLvlEnable;
  64. sysIntLvlDisableRtn = s3c2410xIntLvlDisable;
  65. /* all sources disabled */
  66. s3c2410xIntLvlEnabled = 0;
  67. return OK;
  68. }
  69. /*
  70.  * s3c2410xIntLvlVecChk - check for and return any pending interrupts
  71.  *
  72.  * This routine interrogates the hardware to determine the highest priority
  73.  * interrupt pending.  It returns the vector associated with that interrupt, and
  74.  * also the interrupt priority level prior to the interrupt (not the
  75.  * level of the interrupt).  The current interrupt priority level is then
  76.  * raised to the level of the current interrupt so that only higher priority
  77.  * interrupts will be accepted until this interrupt is finished.
  78.  *
  79.  * The return value ERROR indicates that no pending interrupt was found and
  80.  * that the level and vector values were not returned.
  81.  *
  82.  * RETURNS: OK or ERROR if no interrupt is pending.
  83.  */
  84. STATUS  s3c2410xIntLvlVecChk
  85. (
  86. int* pLevel,  /* ptr to receive old interrupt level */
  87. int* pVector  /* ptr to receive current interrupt vector */
  88. )
  89. {
  90. UINT32 tempUINT32;
  91. /* Read pending interrupt register and mask undefined bits */
  92. s3c2410x_INT_REG_READ(s3c2410x_INT_CSR_INTPND, tempUINT32);
  93. /* If no interrupt is pending, return ERROR */
  94. if((tempUINT32 & s3c2410x_INT_CSR_MASK_VAL) == 0) return ERROR;
  95. /* get the number of the pending interrupt */
  96. s3c2410x_INT_REG_READ(s3c2410x_INT_CSR_INTOFFSET, tempUINT32);
  97. *pVector = tempUINT32;
  98. /* Ack interrupt for this level. */
  99. if((1<<tempUINT32)&((1<<INT_LVL_ADC)|(1<<INT_LVL_UART_0)|(1<<INT_LVL_UART_1)|(1<<INT_LVL_UART_2)))
  100. {
  101. s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTSUBMSK, 0x7ff);
  102. }
  103. /* s3c2410xIntLvlDisable(tempUINT32); */
  104. s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_SRCPND, (1<<tempUINT32));
  105. s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTPND, (1<<tempUINT32));
  106. return OK;
  107. }
  108. /*
  109.  * s3c2410xIntLvlEnable - enable a single interrupt level
  110.  *
  111.  * Enable a specific interrupt level.  The enabled level will be allowed to
  112.  * generate an interrupt, when the overall interrupt level is set below the
  113.  * specified level.  Without being enabled, the interrupt is blocked regardless
  114.  * of the overall interrupt level setting.
  115.  *
  116.  * RETURNS: OK or ERROR if the specified level cannot be enabled.
  117.  */
  118. STATUS  s3c2410xIntLvlEnable
  119. (
  120. int level  /* level to be enabled */
  121. )
  122. {
  123. int key;
  124. if(level < 0 || level >= s3c2410x_INT_NUM_LEVELS) return ERROR;
  125. /* set bit in enable mask */
  126. key = intLock();
  127. s3c2410xIntLvlEnabled |= (1 << level);
  128. s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTMSK, ((~s3c2410xIntLvlEnabled) & s3c2410x_INT_CSR_MASK_VAL));
  129. intUnlock(key);
  130. return OK;
  131. }
  132. /*
  133.  * s3c2410xIntLvlDisable - disable a single interrupt level
  134.  *
  135.  * Disable a specific interrupt level.  The disabled level is prevented
  136.  * from generating an interrupt even if the overall interrupt level is set
  137.  * below the specified level.
  138.  *
  139.  * RETURNS: OK or ERROR, if the specified interrupt level cannot be disabled.
  140.  */
  141. STATUS  s3c2410xIntLvlDisable
  142. (
  143. int level  /* level to be disabled */
  144. )
  145. {
  146. int key;
  147. if(level < 0 || level >= s3c2410x_INT_NUM_LEVELS) return ERROR;
  148. /* clear bit in enable mask */
  149. key = intLock();
  150. s3c2410xIntLvlEnabled &= ~(1 << level);
  151. s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTMSK, ((~s3c2410xIntLvlEnabled) & s3c2410x_INT_CSR_MASK_VAL));
  152. intUnlock(key);
  153. return OK;
  154. }