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

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 sysIntLvlVecAckRtn;
  6. IMPORT FUNCPTR sysIntLvlVecChkRtn;
  7. IMPORT FUNCPTR sysIntLvlEnableRtn;
  8. IMPORT FUNCPTR sysIntLvlDisableRtn;
  9. /* hardware access methods */
  10. #ifndef s3c2410x_INT_REG_READ
  11. #define s3c2410x_INT_REG_READ(reg,result) 
  12. ((result) = *((volatile UINT32 *)(reg)))
  13. #endif
  14. #ifndef s3c2410x_INT_REG_WRITE
  15. #define s3c2410x_INT_REG_WRITE(reg,data) 
  16. (*((volatile UINT32 *)(reg)) = (data))
  17. #endif
  18. #define  s3c2410x_REG_READ(reg)  
  19.   (*((volatile UINT32 *)(reg)))
  20. /* Local data 
  21. #define s3c2410x_INT_ALL_ENABLED (s3c2410x_INT_NUM_LEVELS)
  22. #define s3c2410x_INT_ALL_DISABLED (s3c2410x_INT_NUM_LEVELS-1)
  23. */
  24. /* Current interrupt level setting (s3c2410xIntLvlChg). */
  25. /*LOCAL UINT32 s3c2410xIntLvlCurrent = s3c2410x_INT_ALL_DISABLED;  all levels disabled */
  26. /* 
  27.  * A mask word.  Bits are set in this word when a specific level
  28.  * is enabled. It is used to mask off individual levels that have
  29.  * not been explicitly enabled.
  30.  */
  31. LOCAL UINT32 s3c2410xIntLvlEnabled;
  32. /* forward declarations */
  33. STATUS s3c2410xIntLvlVecChk (int*, int*);
  34. STATUS s3c2410xInitLvVecAck (int, int);
  35. STATUS s3c2410xIntLvlEnable (int);
  36. STATUS s3c2410xIntLvlDisable(int);
  37. /*
  38.  * s3c2410xIntDevInit - initialize the interrupt controller
  39.  *
  40.  * This routine will:
  41.  * <1> Initialize the interrupt controller device;
  42.  * <2> Disabling all interrupt sources;
  43.  * <3> Connect the device driver specific routines into the architecture level hooks.
  44.  *
  45.  * If the BSP needs to create a wrapper routine around any of the arhitecture level routines,
  46.  * it should install the pointer to the wrapper routine after calling this routine.
  47.  * 
  48.  * RETURNS: N/A.
  49.  */
  50. int s3c2410xIntDevInit (void)
  51. {
  52. UINT32 tempUINT32 = 0;
  53. /* <1> Initialize the interrupt controller device; */
  54. s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTMSK,0xfeffffbf); /* Mask all Interrupt. */
  55. s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTSUBMSK,0x7ff); /* Mask all subInterrupt. */
  56. s3c2410x_INT_REG_READ(s3c2410x_INT_CSR_SUBSRCPND,tempUINT32);
  57. s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_SUBSRCPND,tempUINT32); /* Clear SUBSRCPND */
  58. s3c2410x_INT_REG_READ(s3c2410x_INT_CSR_SRCPND,tempUINT32);
  59. s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_SRCPND,tempUINT32); /* Clear SRCPND */
  60. s3c2410x_INT_REG_READ(s3c2410x_INT_CSR_INTPND,tempUINT32);
  61. s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTPND,tempUINT32); /* Clear INTPND. */
  62. s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTMOD,0); /* Select IRQ mode. */
  63. s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_PRIORITY,0); /* Set priority. */
  64. s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_EINTSTYLE,EINT0_7_STYLE);
  65. /* <3> Install the driver routines in the architecture hooks */
  66. sysIntLvlVecChkRtn = s3c2410xIntLvlVecChk;
  67. sysIntLvlVecAckRtn  = s3c2410xInitLvVecAck;
  68. sysIntLvlEnableRtn = s3c2410xIntLvlEnable;
  69. sysIntLvlDisableRtn = s3c2410xIntLvlDisable;
  70. /* all sources disabled */
  71. s3c2410xIntLvlEnabled = 0;
  72. return OK;
  73. }
  74. /*
  75.  * s3c2410xIntLvlVecChk - check for and return any pending interrupts
  76.  *
  77.  * This routine interrogates the hardware to determine the highest priority
  78.  * interrupt pending.  It returns the vector associated with that interrupt, and
  79.  * also the interrupt priority level prior to the interrupt (not the
  80.  * level of the interrupt).  The current interrupt priority level is then
  81.  * raised to the level of the current interrupt so that only higher priority
  82.  * interrupts will be accepted until this interrupt is finished.
  83.  *
  84.  * The return value ERROR indicates that no pending interrupt was found and
  85.  * that the level and vector values were not returned.
  86.  *
  87.  * RETURNS: OK or ERROR if no interrupt is pending.
  88.  */
  89. STATUS  s3c2410xIntLvlVecChk
  90. (
  91. int* pLevel,  /* ptr to receive old interrupt level */
  92. int* pVector  /* ptr to receive current interrupt vector */
  93. )
  94. {
  95. UINT32 tempUINT32;
  96. UINT32 tempUINT32_1;
  97. UINT32 tempUINT32_2;
  98. UINT32 irq2 = INT_LVL_ADC;
  99. volatile unsigned int  *p1,*p2,*p3;
  100. p1 = (volatile unsigned int *)(0x56000050);
  101. p2 = (volatile unsigned int *)(0x56000058);
  102. p3 = (volatile unsigned int *)(0x56000054);
  103. *p1 = 0x55aa;
  104. *p2 = 0x0; 
  105. /* Read pending interrupt register and mask undefined bits */
  106. s3c2410x_INT_REG_READ(s3c2410x_INT_CSR_INTPND, tempUINT32_2);
  107. /* If no interrupt is pending, return ERROR */
  108. if((tempUINT32_2 & s3c2410x_INT_CSR_MASK_VAL) == 0) 
  109. {  
  110.     return ERROR;
  111. }
  112.     /* get the number of the pending interrupt */
  113. s3c2410x_INT_REG_READ(s3c2410x_INT_CSR_INTOFFSET, tempUINT32);     
  114. s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_SRCPND, (1<<tempUINT32));
  115. s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTPND, (1<<tempUINT32));
  116. /*s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTMSK, (1<<5));*/
  117. /*Ack interrupt for this level.*/ 
  118. if((1<<tempUINT32)&((1<<INT_LVL_ADC)|(1<<INT_LVL_UART_0)|(1<<INT_LVL_UART_1)|(1<<INT_LVL_UART_2)))
  119. {
  120.         /*s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTMSK,s3c2410x_REG_READ(s3c2410x_INT_CSR_INTMSK)|(1<<28));*/
  121. s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTSUBMSK, 0x7ff);   
  122. }
  123. if((tempUINT32_2 & (1<<5))||(tempUINT32_2 & (1<<4)))
  124. {
  125. s3c2410x_INT_REG_READ(s3c2410x_INT_CSR_EINTPEND, tempUINT32_1);
  126. s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_EINTPEND, tempUINT32_1);
  127.   if (((tempUINT32_1) == 0)&&(tempUINT32 == 5))
  128.     {   
  129. *p3 = 0xFf;
  130. return ERROR;
  131.     }
  132.     if ((tempUINT32_1 & (~(0xf))) == 0)
  133.     {   
  134.            /* *p3 = 0x2f;*/
  135. return ERROR;
  136.     } 
  137. tempUINT32_2 = tempUINT32_1; 
  138.     
  139.     tempUINT32_1 = tempUINT32_1 >> 4;
  140.     
  141.     while (tempUINT32_1 != 0) {
  142.                 tempUINT32_1 >>= 1;
  143.                 irq2++;
  144.             }
  145.     tempUINT32 = irq2; 
  146.    if(tempUINT32 == 37) 
  147.     {/*s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTMSK, (1<<5));*/
  148.      s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_EINTMASK, s3c2410x_REG_READ(s3c2410x_INT_CSR_EINTMASK)|(1<<9));
  149.          
  150.     /**p3 = 0x1f;*/
  151.     }
  152.     else
  153.      {
  154.     /* *p3 = 0x3f;*/
  155.      }
  156.       
  157.   
  158.   }
  159.   
  160.   *pVector = tempUINT32; 
  161. return OK;
  162. }
  163. STATUS s3c2410xInitLvVecAck
  164. (
  165. int Level,  /* ptr to receive old interrupt level */
  166. int Vector  /* ptr to receive current interrupt vector */
  167. )
  168. {
  169. volatile unsigned int  *p1,*p2,*p3;
  170. p1 = (volatile unsigned int *)(0x56000050);
  171. p2 = (volatile unsigned int *)(0x56000058);
  172. p3 = (volatile unsigned int *)(0x56000054);
  173. *p1 = 0x55aa;
  174. *p2 = 0x0; 
  175. if (Vector == 37)
  176. {
  177.     *p3 = 0x3f; 
  178. /*s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTMSK,s3c2410x_REG_READ(s3c2410x_INT_CSR_INTMSK)&(~(1<<5)));*/
  179. /*s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_EINTMASK,s3c2410x_REG_READ(s3c2410x_INT_CSR_EINTMASK)&(~(1<<9)));*/
  180. }
  181. #if 0
  182. int key;
  183. int temp;
  184. volatile unsigned int  *p1,*p2,*p3;
  185. p1 = (volatile unsigned int *)(0x56000050); p2 = (volatile unsigned int *)(0x56000058); p3 = (volatile unsigned int *)(0x56000054); *p1 = 0x55aa; *p2 = 0x0; 
  186. if(Vector < 0 || Vector >= s3c2410x_INT_NUM_LEVELS)
  187. {
  188.         *p3 = 0x4F;
  189. return ERROR;
  190. }
  191. /* set bit in enable mask */
  192. key = intLock();
  193. if (Vector > IRQ_EINT7)
  194. {  
  195.     temp = (Vector - IRQ_EINT4);
  196.     temp = 1<<(temp+4);
  197.     s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_EINTPEND,temp);
  198.     Vector = INT_LVL_EINT_8_23;  
  199.   }
  200.   else if(Vector > INT_LVL_ADC)
  201.   {
  202.     temp = (Vector - IRQ_EINT4);
  203.     temp = 1<<(temp+4);
  204.     s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_EINTPEND,temp);
  205.     Vector = INT_LVL_EINT_4_7;   
  206.   }
  207. s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_SRCPND, 1<<Vector);
  208. s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTPND, 1<<Vector);
  209. intUnlock(key);
  210.      *p3 = 0x5F;
  211. return OK;
  212. #endif
  213. }
  214. /*
  215.  * s3c2410xIntLvlEnable - enable a single interrupt level
  216.  *
  217.  * Enable a specific interrupt level.  The enabled level will be allowed to
  218.  * generate an interrupt, when the overall interrupt level is set below the
  219.  * specified level.  Without being enabled, the interrupt is blocked regardless
  220.  * of the overall interrupt level setting.
  221.  *
  222.  * RETURNS: OK or ERROR if the specified level cannot be enabled.
  223.  */
  224. STATUS  s3c2410xIntLvlEnable
  225. (
  226. int level  /* level to be enabled */
  227. )
  228. {
  229. int key;
  230. int temp;
  231. if(level < 0 || level >= s3c2410x_INT_NUM_LEVELS) return ERROR;
  232. /* set bit in enable mask */
  233. key = intLock();
  234. /*
  235. if(level == 37)
  236. {
  237. volatile unsigned int  *p1,*p2,*p3;
  238. p1 = (volatile unsigned int *)(0x56000050);
  239. p2 = (volatile unsigned int *)(0x56000058);
  240. p3 = (volatile unsigned int *)(0x56000054);
  241. *p1 = 0x55aa;
  242. *p2 = 0x0; 
  243. *p3 = 0xef;
  244. }
  245. */
  246. if (level > IRQ_EINT7)
  247. {
  248.     temp = (level - IRQ_EINT4);
  249.     temp = 1<<(temp+4);
  250. s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_EINTPEND,temp);
  251.     s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_EINTMASK,s3c2410x_REG_READ(s3c2410x_INT_CSR_EINTMASK)&(~temp));
  252. level = INT_LVL_EINT_8_23;  
  253.   }
  254.   else if(level > INT_LVL_ADC)
  255.   {
  256.     temp = (level - IRQ_EINT4);
  257.     temp = 1<<(temp+4);
  258. s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_EINTPEND,temp);
  259.     s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_EINTMASK,s3c2410x_REG_READ(s3c2410x_INT_CSR_EINTMASK)&(~temp));
  260.     level = INT_LVL_EINT_4_7;   
  261.   }
  262. s3c2410xIntLvlEnabled |= (1 << level);
  263. s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_SRCPND,1<<level);
  264. s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTPND,1<<level);
  265. s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTMSK, ((~s3c2410xIntLvlEnabled) & s3c2410x_INT_CSR_MASK_VAL));
  266. intUnlock(key);
  267. return OK;
  268. }
  269. /*
  270.  * s3c2410xIntLvlDisable - disable a single interrupt level
  271.  *
  272.  * Disable a specific interrupt level.  The disabled level is prevented
  273.  * from generating an interrupt even if the overall interrupt level is set
  274.  * below the specified level.
  275.  *
  276.  * RETURNS: OK or ERROR, if the specified interrupt level cannot be disabled.
  277.  */
  278. STATUS  s3c2410xIntLvlDisable
  279. (
  280. int level  /* level to be disabled */
  281. )
  282. {
  283. int key;
  284.     unsigned int temp;
  285. if(level < 0 || level >= s3c2410x_INT_NUM_LEVELS) return ERROR;
  286. /* clear bit in enable mask */
  287. key = intLock();
  288. if (level > IRQ_EINT7)
  289. {
  290.     temp = (level - IRQ_EINT4);
  291.     temp = 1<<(temp+4);
  292.     s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_EINTMASK,s3c2410x_REG_READ(s3c2410x_INT_CSR_EINTMASK)|(temp));
  293.     level = INT_LVL_EINT_8_23;  
  294.   }
  295.   else if(level > INT_LVL_ADC)
  296.   {
  297.     temp = (level - IRQ_EINT4);
  298.     temp = 1<<(temp+4);
  299.     s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_EINTMASK,s3c2410x_REG_READ(s3c2410x_INT_CSR_EINTMASK)|(temp));
  300.     level = INT_LVL_EINT_4_7;   
  301.   }
  302. s3c2410xIntLvlEnabled &= ~(1 << level);
  303. s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTMSK, ((~s3c2410xIntLvlEnabled) & s3c2410x_INT_CSR_MASK_VAL));
  304. intUnlock(key);
  305. return OK;
  306. }