xref: /nrf52832-nimble/rt-thread/libcpu/arm/lpc214x/cpuport.c (revision 104654410c56c573564690304ae786df310c91fc)
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