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