ihndlr_lpc2xxx.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. /****************************************************************************
  2. * This file is part of the Ethernut port for the LPC2XXX
  3. *
  4. * Copyright (c) 2005 by Michael Fischer. All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. *
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * 3. Neither the name of the author nor the names of its contributors may
  16. * be used to endorse or promote products derived from this software
  17. * without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  22. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
  23. * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  24. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  25. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  26. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  27. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  28. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  29. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  30. * SUCH DAMAGE.
  31. *
  32. ****************************************************************************
  33. *
  34. * History:
  35. *
  36. * 24.09.05 mifi First Version
  37. * The CrossWorks for ARM toolchain will be used. Some of
  38. * this functions looks similar like my ARM uC/OS port for
  39. * CrossWorks because I have done it before (AN-1711B).
  40. * For some bit definition and information, take a look
  41. * in the LPC2119/2129/2194/2292/2294 user manual 2004 May 03.
  42. ****************************************************************************/
  43. #define __IHNDLR_LPC2XXX_C__
  44. #include <arch/arm/lpc2xxx.h>
  45. #include <stdio.h>
  46. /*=========================================================================*/
  47. /* DEFINE: All Structures and Common Constants */
  48. /*=========================================================================*/
  49. /*
  50. * Take a look in the LPC2294 user manual (2004 May 03) page 52
  51. */
  52. #define UNDEFINED_INSTRUCTION_VECTOR_ADDR (*(uint32_t *)0x00000004L)
  53. #define SOFTWARE_INTERRUPT_VECTOR_ADDR (*(uint32_t *)0x00000008L)
  54. #define PREFETCH_ABORT_VECTOR_ADDR (*(uint32_t *)0x0000000CL)
  55. #define DATA_ABORT_VECTOR_ADDR (*(uint32_t *)0x00000010L)
  56. #define IRQ_VECTOR_ADDR (*(uint32_t *)0x00000018L)
  57. #define FIQ_VECTOR_ADDR (*(uint32_t *)0x0000001CL)
  58. #define DATA_ABORT_ISR_ADDR (*(uint32_t *)0x00000030L)
  59. #define IRQ_ISR_ADDR (*(uint32_t *)0x00000038L)
  60. #define FIQ_ISR_ADDR (*(uint32_t *)0x0000003CL)
  61. typedef void (*FNCPTR)(void);
  62. /*=========================================================================*/
  63. /* DEFINE: Definition of all local Data */
  64. /*=========================================================================*/
  65. /*=========================================================================*/
  66. /* DEFINE: Definition of all local Procedures */
  67. /*=========================================================================*/
  68. /***************************************************************************/
  69. /* VICInit */
  70. /* */
  71. /* This function will "init" the VIC. */
  72. /* */
  73. /* In : none */
  74. /* Out : none */
  75. /* Return: none */
  76. /***************************************************************************/
  77. static void VICInit (void)
  78. {
  79. /*
  80. * Disable ALL interrupts
  81. */
  82. VICIntEnClr = 0xFFFFFFFF;
  83. /*
  84. * VIC register can be accessed in
  85. * User or privileged mode.
  86. */
  87. VICProtection = 0;
  88. /*
  89. * All interrupts assigned to IRQ category
  90. */
  91. VICIntSelect = 0;
  92. } /* VICInit */
  93. /***************************************************************************/
  94. /* ABORTHandler */
  95. /* */
  96. /* This is the ABORT handler. */
  97. /* */
  98. /* In : none */
  99. /* Out : none */
  100. /* Return: none */
  101. /***************************************************************************/
  102. static void ABORTHandler(void) NUT_IRQ_HANDLER_FUNC;
  103. static void ABORTHandler (void)
  104. {
  105. /*
  106. * The next lines are only used for debugging purpose
  107. */
  108. volatile uint32_t AbortCounter = 0;
  109. AbortCounter++;
  110. } /* ABORTHandler */
  111. /***************************************************************************/
  112. /* IRQHandler */
  113. /* */
  114. /* This is the IRQ handler. If an IRQ occurred, the address of the */
  115. /* ISR can be read from the VICVectAddr. */
  116. /* */
  117. /* 1. Read the address of the IRQHandler to execute from VICVectAddr */
  118. /* 2. But check if the address is NOT 0. */
  119. /* 3. Jump to the IRQHandler */
  120. /* 4. Read VICVectAddr again to check if more interrupts are available */
  121. /* to execute. */
  122. /* */
  123. /* In : none */
  124. /* Out : none */
  125. /* Return: none */
  126. /***************************************************************************/
  127. static void IRQHandler(void) NUT_IRQ_HANDLER_FUNC;
  128. static void IRQHandler (void)
  129. {
  130. FNCPTR fncptr;
  131. fncptr = (FNCPTR)VICVectAddr; /* 1 */
  132. while (fncptr != (FNCPTR)0) { /* 2 */
  133. (*fncptr)(); /* 3 */
  134. fncptr = (FNCPTR)VICVectAddr; /* 4 */
  135. }
  136. } /* IRQHandler */
  137. /***************************************************************************/
  138. /* FIQHandler */
  139. /* */
  140. /* This is the FIQ handler. If an FIQ occurred, the address of the */
  141. /* ISR can be read from the VICVectAddr */
  142. /* */
  143. /* 1. Read the address of the IRQHandler to execute from VICVectAddr */
  144. /* 2. But check if the address is NOT 0. */
  145. /* 3. Jump to the IRQHandler */
  146. /* 4. Read VICVectAddr again to check if more interrupts are available */
  147. /* to execute. */
  148. /* */
  149. /* In : none */
  150. /* Out : none */
  151. /* Return: none */
  152. /***************************************************************************/
  153. static void FIQHandler(void) NUT_FIQ_HANDLER_FUNC;
  154. static void FIQHandler (void)
  155. {
  156. FNCPTR fncptr;
  157. fncptr = (FNCPTR)VICVectAddr; /* 1 */
  158. while (fncptr != (FNCPTR)0) { /* 2 */
  159. (*fncptr)(); /* 3 */
  160. fncptr = (FNCPTR)VICVectAddr; /* 4 */
  161. }
  162. } /* FIQHandler */
  163. /*=========================================================================*/
  164. /* DEFINE: All code exported */
  165. /*=========================================================================*/
  166. /***************************************************************************/
  167. /* InitIrqHandler */
  168. /* */
  169. /* We will map the ARM interrupt vectors to the RAM. */
  170. /* With this trick, the interrupt latency is a less than from flash. */
  171. /* */
  172. /* In : none */
  173. /* Out : none */
  174. /* Return: none */
  175. /***************************************************************************/
  176. void InitIrqHandler (void)
  177. {
  178. /*
  179. * User RAM Mode. Interrupt vecors are re-mapped to Static RAM.
  180. */
  181. MEMMAP = 2;
  182. /*
  183. * I got the information how to setup the interrupt
  184. * handler from the uC/OS port for the ARM. Take a look
  185. * in the application note AN-1014 from micrium.
  186. * (www.micrium.com)
  187. */
  188. /*
  189. * Set IRQHandler
  190. */
  191. IRQ_VECTOR_ADDR = 0xE59FF018; /* LDR PC,[PC,#0x18] instruction */
  192. IRQ_ISR_ADDR = (uint32_t)IRQHandler; /* IRQ exception vector address */
  193. /*
  194. * Set FIQHandler
  195. */
  196. FIQ_VECTOR_ADDR = 0xE59FF018; /* LDR PC,[PC,#0x18] instruction */
  197. FIQ_ISR_ADDR = (uint32_t)FIQHandler; /* FIQ exception vector address */
  198. /*
  199. * We does not need the next interrupt sources in the moment,
  200. * therefore jump to itself.
  201. */
  202. UNDEFINED_INSTRUCTION_VECTOR_ADDR = 0xEAFFFFFE;
  203. SOFTWARE_INTERRUPT_VECTOR_ADDR = 0xEAFFFFFE;
  204. PREFETCH_ABORT_VECTOR_ADDR = 0xEAFFFFFE;
  205. /*
  206. * In case we must find an ABORT error,
  207. * enable the next lines and set a breakpoint
  208. * in ABORTHandler.
  209. */
  210. #if 1
  211. DATA_ABORT_VECTOR_ADDR = 0xE59FF018;
  212. DATA_ABORT_ISR_ADDR = (uint32_t)ABORTHandler;
  213. #endif
  214. /*
  215. * Init the Vectored Interrupt Controller (VIC)
  216. */
  217. VICInit();
  218. } /* InitIrqHandler */
  219. /*** EOF ***/