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 */ 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 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 */ 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 */ 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 */ 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 */ 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 */ 166 void rt_hw_cpu_reset(void) 167 { 168 } 169 170 /** 171 * this function will shutdown CPU 172 * 173 */ 174 void rt_hw_cpu_shutdown() 175 { 176 rt_kprintf("shutdown...\n"); 177 178 while (1); 179 } 180 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 197 void rt_hw_trap_fiq(void) 198 { 199 rt_kprintf("fast interrupt request\n"); 200 } 201 202 /*@}*/ 203