1
0

cpuport.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. /*
  2. * File : cpuport.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2009 - 2011, RT-Thread Development Team
  5. *
  6. * The license and distribution terms for this file may be
  7. * found in the file LICENSE in this distribution or at
  8. * http://www.rt-thread.org/license/LICENSE
  9. *
  10. * Change Logs:
  11. * Date Author Notes
  12. * 2011-06-15 aozima the first version for lpc214x
  13. * 2013-03-29 aozima Modify the interrupt interface implementations.
  14. */
  15. #include <rtthread.h>
  16. #include <rthw.h>
  17. #include "lpc214x.h"
  18. #define MAX_HANDLERS 32
  19. #define SVCMODE 0x13
  20. extern rt_uint32_t rt_interrupt_nest;
  21. /* exception and interrupt handler table */
  22. struct rt_irq_desc irq_desc[MAX_HANDLERS];
  23. /**
  24. * @addtogroup LPC214x
  25. */
  26. /*@{*/
  27. /**
  28. * This function will initialize thread stack
  29. *
  30. * @param tentry the entry of thread
  31. * @param parameter the parameter of entry
  32. * @param stack_addr the beginning stack address
  33. * @param texit the function will be called when thread exit
  34. *
  35. * @return stack address
  36. */
  37. rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
  38. rt_uint8_t *stack_addr, void *texit)
  39. {
  40. unsigned long *stk;
  41. stk = (unsigned long *)stack_addr;
  42. *(stk) = (unsigned long)tentry; /* entry point */
  43. *(--stk) = (unsigned long)texit; /* lr */
  44. *(--stk) = 0; /* r12 */
  45. *(--stk) = 0; /* r11 */
  46. *(--stk) = 0; /* r10 */
  47. *(--stk) = 0; /* r9 */
  48. *(--stk) = 0; /* r8 */
  49. *(--stk) = 0; /* r7 */
  50. *(--stk) = 0; /* r6 */
  51. *(--stk) = 0; /* r5 */
  52. *(--stk) = 0; /* r4 */
  53. *(--stk) = 0; /* r3 */
  54. *(--stk) = 0; /* r2 */
  55. *(--stk) = 0; /* r1 */
  56. *(--stk) = (unsigned long)parameter; /* r0 : argument */
  57. /* cpsr */
  58. if ((rt_uint32_t)tentry & 0x01)
  59. *(--stk) = SVCMODE | 0x20; /* thumb mode */
  60. else
  61. *(--stk) = SVCMODE; /* arm mode */
  62. /* return task's current stack address */
  63. return (rt_uint8_t *)stk;
  64. }
  65. /* exception and interrupt handler table */
  66. rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
  67. rt_uint32_t rt_thread_switch_interrupt_flag;
  68. void rt_hw_interrupt_handler(int vector, void *param)
  69. {
  70. rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
  71. }
  72. /**
  73. * This function will initialize hardware interrupt
  74. */
  75. void rt_hw_interrupt_init(void)
  76. {
  77. rt_base_t index;
  78. rt_uint32_t *vect_addr, *vect_ctl;
  79. /* initialize VIC*/
  80. VICIntEnClr = 0xffffffff;
  81. VICVectAddr = 0;
  82. /* set all to IRQ */
  83. VICIntSelect = 0;
  84. rt_memset(irq_desc, 0x00, sizeof(irq_desc));
  85. for (index = 0; index < MAX_HANDLERS; index ++)
  86. {
  87. irq_desc[index].handler = rt_hw_interrupt_handler;
  88. vect_addr = (rt_uint32_t *)(VIC_BASE_ADDR + 0x100 + (index << 2));
  89. vect_ctl = (rt_uint32_t *)(VIC_BASE_ADDR + 0x200 + (index << 2));
  90. *vect_addr = (rt_uint32_t)&irq_desc[index];
  91. *vect_ctl = 0xF;
  92. }
  93. /* init interrupt nest, and context in thread sp */
  94. rt_interrupt_nest = 0;
  95. rt_interrupt_from_thread = 0;
  96. rt_interrupt_to_thread = 0;
  97. rt_thread_switch_interrupt_flag = 0;
  98. }
  99. /**
  100. * This function will mask a interrupt.
  101. * @param vector the interrupt number
  102. */
  103. void rt_hw_interrupt_mask(int vector)
  104. {
  105. VICIntEnClr = (1 << vector);
  106. }
  107. /**
  108. * This function will un-mask a interrupt.
  109. * @param vector the interrupt number
  110. */
  111. void rt_hw_interrupt_umask(int vector)
  112. {
  113. VICIntEnable = (1 << vector);
  114. }
  115. /**
  116. * This function will install a interrupt service routine to a interrupt.
  117. * @param vector the interrupt number
  118. * @param handler the interrupt service routine to be installed
  119. * @param param the interrupt service function parameter
  120. * @param name the interrupt name
  121. * @return old handler
  122. */
  123. rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
  124. void *param, char *name)
  125. {
  126. rt_isr_handler_t old_handler = RT_NULL;
  127. if(vector >= 0 && vector < MAX_HANDLERS)
  128. {
  129. rt_uint32_t* vect_ctl = (rt_uint32_t *)(VIC_BASE_ADDR + 0x200 + (vector << 2));
  130. /* assign IRQ slot and enable this slot */
  131. *vect_ctl = 0x20 | (vector & 0x1F);
  132. old_handler = irq_desc[vector].handler;
  133. if (handler != RT_NULL)
  134. {
  135. irq_desc[vector].handler = handler;
  136. irq_desc[vector].param = param;
  137. }
  138. }
  139. return old_handler;
  140. }
  141. /**
  142. * this function will reset CPU
  143. *
  144. */
  145. void rt_hw_cpu_reset(void)
  146. {
  147. }
  148. /**
  149. * this function will shutdown CPU
  150. *
  151. */
  152. void rt_hw_cpu_shutdown()
  153. {
  154. rt_kprintf("shutdown...\n");
  155. while (1);
  156. }
  157. void rt_hw_trap_irq(void)
  158. {
  159. int irqno;
  160. struct rt_irq_desc* irq;
  161. extern struct rt_irq_desc irq_desc[];
  162. irq = (struct rt_irq_desc*) VICVectAddr;
  163. irqno = ((rt_uint32_t) irq - (rt_uint32_t) &irq_desc[0])/sizeof(struct rt_irq_desc);
  164. /* invoke isr */
  165. irq->handler(irqno, irq->param);
  166. /* acknowledge Interrupt */
  167. // VICVectAddr = 0;
  168. }
  169. void rt_hw_trap_fiq(void)
  170. {
  171. rt_kprintf("fast interrupt request\n");
  172. }
  173. /*@}*/