首页 > 代码库 > 第三十八天:Tiny4412驱动开发之外部中断
第三十八天:Tiny4412驱动开发之外部中断
在三天前学习按键驱动的时候,按键通过轮循的方式,一直在等待被按下,这时候系统不能够完成其它的操作,这明显是不科学的,可以使用外部中断解决这个问题。
在Tiny4412中中断分为三种 分别是软件通用中断(SGI),私有设备中断(PPI),共享设备中断(SPI)。
一共有160个中断号,中断表在Tiny4412手册的745页。前篇写的看门狗中断属于PPI,今天的实验所使用的是SPI。也可以称为外部中断。
前几天的按键驱动篇章我们已经找到按键KEY1对应的寄存器为GPX3_2。查看GPX3CON[2]的描述可知,将其置为0xf,为外部中断模式
对应的中断描述在EXT_INT43[2]中。
有关于EXT_INT43[2]的寄存器: EXT_INT43_CON[2] 选择中断触发方式、
中断开关:EXT_INT43_MASK[2]:
中断状态:EXT_INT43_PEND[2],特别注意的是,要清中断,将值赋值为1.
通过下图可知中断源是26,通过表格查找到中断号为64:
具体代码如下所示:
1 #include "regs.h" 2 3 int (*printf)(char *, ...) = 0xc3e114d8; 4 5 void init_ttb(unsigned long *ttb); 6 void enable_mmu(void); 7 void memcpy(unsigned char *dest, unsigned char *source, int len); 8 void do_irq(); 9 10 int main() 11 { 12 13 enable_mmu(); 14 *(unsigned long *)0x67000000 = do_irq; 15 unsigned long source = 0; 16 __asm__ __volatile__( 17 "ldr %0, =vector_start\n" 18 : "=r" (source) 19 ); 20 memcpy(0, source, 0x1000); 21 22 //step 1: set cpsr i bit 23 __asm__ __volatile__( 24 "mrs r0, cpsr\n" 25 "bic r0, r0, #0x80\n" 26 "msr cpsr, r0\n" 27 ::: "r0" 28 ); 29 30 //step 2: enable gic 31 ICCICR_CPU0 = 1;//终端总开关 32 ICCPMR_CPU0 = 0xff;//设置最低优先级 33 ICDDCR = 1; 34 35 //中断源为64 36 ICDIPR16_CPU0 &= ~0xff ;//设置本中断优先级 37 ICDIPTR16_CPU0 &= 0xff ;// 选择指定的cpu0进行终端处理 38 ICDIPTR16_CPU0 |= 1; // 选择指定的cpu0进行终端处理 39 ICDISER2_CPU0 = 1;//设置本中断开启 40 41 //step 3: set gpio 42 GPX3CON |= (0xf << 8);//使用外部中断模式 43 //step 4: set xeint26 44 EXT_INT43CON &= ~(0x7 << 8); 45 EXT_INT43CON |= ( 2 << 8);//设置中断方式 46 EXT_INT43MASK &= ~(1 << 2);//开中断 47 //step 5 48 printf("welcom back\n"); 49 } 50 51 void do_irq() 52 { 53 printf("key 1 ~~~ \n"); 54 /*清中断*/ 55 EXT_INT43PEND |= (0x1 << 2); 56 } 57 58 __asm__( 59 "vector_start:\n" 60 "b reset\n" 61 "b undef\n" 62 "b swi\n" 63 "b pre_abt\n" 64 "b data_abt\n" 65 ".word 0x0\n" 66 "b irq \n" 67 "b fiq\n" 68 "\n" 69 "reset:\n" 70 "undef:\n" 71 "mov sp, #0x66000000\n" 72 "stmfd sp!, {r0-r12, lr}\n" 73 "\n" 74 "mov r0, #0x67000000\n" 75 "ldr r1, [r0]\n" 76 "blx r1\n" 77 "\n" 78 "mov sp, #0x66000000\n" 79 "ldmea sp, {r0-r12, pc}^\n" 80 "swi:\n" 81 "mov sp, #0x66000000\n" 82 "stmfd sp!, {r0-r12, lr}\n" 83 "\n" 84 "mov r0, #0x67000000\n" 85 "ldr r1, [r0]\n" 86 "blx r1\n" 87 "\n" 88 "mov sp, #0x66000000\n" 89 "ldmea sp, {r0-r12, pc}^\n" 90 "\n" 91 "pre_abt:\n" 92 "data_abt:\n" 93 "mov sp, #0x66000000\n" 94 "sub lr, lr, #4\n" 95 "stmfd sp!, {r0-r12, lr}\n" 96 "\n" 97 "mov r0, #0x67000000\n" 98 "ldr r1, [r0]\n" 99 "blx r1\n"100 "\n"101 "mov sp, #0x66000000\n"102 "ldmea sp, {r0-r12, pc}^\n"103 "irq:\n"104 "mov sp, #0x66000000\n"105 "sub lr, lr, #4\n"106 "stmfd sp!, {r0-r12, lr}\n"107 108 "mov r0, #0x67000000\n"109 "ldr r1, [r0]\n"110 "blx r1\n"111 112 "mov sp, #0x66000000\n"113 "ldmea sp, {r0-r12, pc}^\n"114 "fiq:\n"115 116 );117 118 void init_ttb(unsigned long *ttb)119 {120 unsigned long va = 0;121 unsigned long pa = 0;122 123 //00000000~10000000 -> 60000000~64000000124 for(va=0x00000000; va<0x10000000; va+=0x100000){125 pa = va + 0x60000000;126 ttb[va >> 20] = pa | 2;127 }128 129 //10000000~14000000 -> 10000000~14000000130 for(va=0x10000000; va<0x14000000; va+=0x100000){131 pa = va;132 ttb[va >> 20] = pa | 2;133 }134 135 //40000000~80000000 -> 40000000~80000000136 for(va=0x40000000; va<0x80000000; va+=0x100000){137 pa = va;138 ttb[va >> 20] = pa | 2;139 }140 141 //30000000~40000000 -> 50000000~60000000142 for(va=0x30000000; va<0x40000000; va+=0x100000){143 pa = va + 0x20000000;144 ttb[va >> 20] = pa | 2;145 }146 }147 148 void enable_mmu(void)149 {150 unsigned long ttb = 0x70000000;151 init_ttb(ttb);152 unsigned long mmu = 0;153 mmu = 1 | (1 << 3) | (1 << 8);154 __asm__ __volatile__(155 "mov r0, #3\n"156 "mcr p15, 0, r0, c3, c0, 0\n" 157 "mcr p15, 0, %0, c2, c0, 0\n" 158 "mcr p15, 0, %1, c1, c0, 0\n" 159 :160 : "r" (ttb), "r" (mmu)161 );162 }163 164 void memcpy(unsigned char *dest, unsigned char *source, int len)165 {166 int i = 0;167 for(i=0; i<len; i++)168 dest[i] = source[i];169 }
#define gpiobase 0x11000000#define GPM4CON (*(volatile unsigned long *)(gpiobase + 0x02E0)) #define GPM4DAT (*(volatile unsigned long *)(gpiobase + 0x02E4))#define GPX3CON (*(volatile unsigned long *)(gpiobase + 0x0C60))#define GPX3DAT (*(volatile unsigned long *)(gpiobase + 0x0C64))#define ICC 0x10480000#define ICCICR_CPU0 (*(volatile unsigned long *)(ICC + 0x0000)) #define ICCPMR_CPU0 (*(volatile unsigned long *)(ICC + 0x0004)) #define ICCBPR_CPU0 (*(volatile unsigned long *)(ICC + 0x0008)) #define ICCIAR_CPU0 (*(volatile unsigned long *)(ICC + 0x000C)) #define ICCEOIR_CPU0 (*(volatile unsigned long *)(ICC + 0x0010)) #define ICCRPR_CPU0 (*(volatile unsigned long *)(ICC + 0x0014)) #define ICCHPIR_CPU0 (*(volatile unsigned long *)(ICC + 0x0018)) #define ICCABPR_CPU0 (*(volatile unsigned long *)(ICC + 0x001C)) #define INTEG_EN_C_CPU0 (*(volatile unsigned long *)(ICC + 0x0040)) #define ICCIIDR (*(volatile unsigned long *)(ICC + 0x00FC))#define ICD 0x10490000#define ICDDCR (*(volatile unsigned long *)(ICD + 0x0000))#define ICDICTR (*(volatile unsigned long *)(ICD + 0x0004))#define ICDIIDR (*(volatile unsigned long *)(ICD + 0x0008))#define ICDISR0_CPU0 (*(volatile unsigned long *)(ICD + 0x0080))#define ICDISER0_CPU0 (*(volatile unsigned long *)(ICD + 0x0100))#define ICDISER2_CPU0 (*(volatile unsigned long *)(ICD + 0x0108))#define ICDICER0_CPU0 (*(volatile unsigned long *)(ICD + 0x0180))#define ICDISPR0_CPU0 (*(volatile unsigned long *)(ICD + 0x0200))#define ICDICPR0_CPU0 (*(volatile unsigned long *)(ICD + 0x0280))#define ICDABR0_CPU0 (*(volatile unsigned long *)(ICD + 0x0300))#define ICDIPR0_CPU0 (*(volatile unsigned long *)(ICD + 0x0400))#define ICDIPR1_CPU0 (*(volatile unsigned long *)(ICD + 0x0404))#define ICDIPR2_CPU0 (*(volatile unsigned long *)(ICD + 0x0408))#define ICDIPR3_CPU0 (*(volatile unsigned long *)(ICD + 0x040C))#define ICDIPR4_CPU0 (*(volatile unsigned long *)(ICD + 0x0410))#define ICDIPR5_CPU0 (*(volatile unsigned long *)(ICD + 0x0414))#define ICDIPR6_CPU0 (*(volatile unsigned long *)(ICD + 0x0418))#define ICDIPR7_CPU0 (*(volatile unsigned long *)(ICD + 0x041C))#define ICDIPR18_CPU0 (*(volatile unsigned long *)(ICD + 0x0448))#define ICDIPR16_CPU0 (*(volatile unsigned long *)(ICD + 0x0440))#define ICDIPTR0_CPU0 (*(volatile unsigned long *)(ICD + 0x0800))#define ICDIPTR1_CPU0 (*(volatile unsigned long *)(ICD + 0x0804))#define ICDIPTR18_CPU0 (*(volatile unsigned long *)(ICD + 0x0848))#define ICDIPTR16_CPU0 (*(volatile unsigned long *)(ICD + 0x0840))#define ICDSGIR (*(volatile unsigned long *)(ICD + 0x0F00))#define WTCON (*(volatile unsigned long *)0x10060000) #define WTDAT (*(volatile unsigned long *)0x10060004) #define WTCNT (*(volatile unsigned long *)0x10060008) #define WTCLRINT (*(volatile unsigned long *)0x1006000C) #define EXT_INT43CON (*(volatile unsigned long *)0x11000E0C) #define EXT_INT43MASK (*(volatile unsigned long *)0x11000F0C) #define EXT_INT43PEND (*(volatile unsigned long *)0x11000F4C)
最后将看门狗中断和按键中断结合起来:实现按下KEY1后LED灯闪烁,在按下后停止闪烁。
1 #include "regs.h" 2 3 int (*printf)(char *, ...) = 0xc3e114d8; 4 5 void init_ttb(unsigned long *ttb); 6 void enable_mmu(void); 7 void memcpy(unsigned char *dest, unsigned char *source, int len); 8 void do_irq(); 9 void led_on(); 10 void led_off(); 11 void wdt_on(); 12 void wdt_off(); 13 14 int main() 15 { 16 enable_mmu(); 17 18 *(unsigned long *)0x67000000 = do_irq; 19 unsigned long source = 0; 20 __asm__ __volatile__( 21 "ldr %0, =vector_start\n" 22 : "=r" (source) 23 ); 24 memcpy(0, source, 0x1000); 25 26 //step 1: set cpsr i bit 27 __asm__ __volatile__( 28 "mrs r0, cpsr\n" 29 "bic r0, r0, #0x80\n" 30 "msr cpsr, r0\n" 31 ::: "r0" 32 ); 33 34 //step 2: enable gic 35 ICCICR_CPU0 = 1; 36 ICCPMR_CPU0 = 0xff; 37 ICDDCR = 1; 38 39 //64 40 ICDIPR16_CPU0 &= ~0xff; 41 ICDIPTR16_CPU0 &= ~0xff; 42 ICDIPTR16_CPU0 |= 1; 43 ICDISER2_CPU0 = 1; 44 45 ICDIPR18_CPU0 &= ~(0xff << 24); 46 ICDIPTR18_CPU0 &= ~(0xff << 24); 47 ICDIPTR18_CPU0 |= (1 << 24); 48 ICDISER2_CPU0 = (1 << 11); 49 50 //step 3: set gpio 51 GPX3CON |= (0xf << 8); 52 53 //step 4: set xeint26 54 EXT_INT43CON &= ~(0x7 << 8); 55 EXT_INT43CON |= (2 << 8); 56 EXT_INT43MASK &= ~(1 << 2); 57 58 //step 5: key down 59 } 60 61 void do_irq() 62 { 63 unsigned long data =http://www.mamicode.com/ ICCIAR_CPU0; 64 unsigned long irq = data & 0x3ff; 65 ICCEOIR_CPU0 = irq; 66 67 if(irq == 64){ 68 if(EXT_INT43PEND & (1 << 2)){ 69 EXT_INT43PEND |= (1 << 2); 70 printf("key 1 down\n"); 71 static int flag = 1; 72 if(flag){ 73 wdt_on(); 74 flag = 0; 75 } 76 else{ 77 wdt_off(); 78 led_off(); 79 flag = 1; 80 } 81 } 82 } 83 if(irq == 75){ 84 WTCLRINT = 1005; 85 printf("wang wang wang\n"); 86 static int flag = 1; 87 if(flag){ 88 flag = 0; 89 led_on(); 90 } 91 else{ 92 led_off(); 93 flag = 1; 94 } 95 } 96 } 97 98 __asm__( 99 "vector_start:\n"100 " b reset\n"101 " b undef\n"102 " b swi\n"103 " b pre_abt\n"104 " b data_abt\n"105 " .word 0x0\n"106 " b irq \n"107 " b fiq\n"108 "\n"109 "reset:\n"110 "undef:\n"111 " mov sp, #0x66000000\n"112 " stmfd sp!, {r0-r12, lr}\n"113 " \n"114 " mov r0, #0x67000000\n"115 " ldr r1, [r0]\n"116 " blx r1\n"117 " \n"118 " mov sp, #0x66000000\n"119 " ldmea sp, {r0-r12, pc}^\n"120 "swi:\n"121 " mov sp, #0x66000000\n"122 " stmfd sp!, {r0-r12, lr}\n"123 " \n"124 " mov r0, #0x67000000\n"125 " ldr r1, [r0]\n"126 " blx r1\n"127 " \n"128 " mov sp, #0x66000000\n"129 " ldmea sp, {r0-r12, pc}^\n"130 "\n"131 "pre_abt:\n"132 "data_abt:\n"133 " mov sp, #0x66000000\n"134 " sub lr, lr, #4\n"135 " stmfd sp!, {r0-r12, lr}\n"136 " \n"137 " mov r0, #0x67000000\n"138 " ldr r1, [r0]\n"139 " blx r1\n"140 " \n"141 " mov sp, #0x66000000\n"142 " ldmea sp, {r0-r12, pc}^\n"143 "irq:\n"144 " mov sp, #0x66000000\n"145 " sub lr, lr, #4\n"146 " stmfd sp!, {r0-r12, lr}\n"147 148 " mov r0, #0x67000000\n"149 " ldr r1, [r0]\n"150 " blx r1\n"151 152 " mov sp, #0x66000000\n"153 " ldmea sp, {r0-r12, pc}^\n"154 "fiq:\n"155 156 );157 158 void init_ttb(unsigned long *ttb)159 {160 unsigned long va = 0;161 unsigned long pa = 0;162 163 for(va=0x00000000; va<0x10000000; va+=0x100000){164 pa = va + 0x60000000;165 ttb[va >> 20] = pa | 2;166 }167 168 //10000000~14000000 -> 10000000~14000000169 for(va=0x10000000; va<0x14000000; va+=0x100000){170 pa = va;171 ttb[va >> 20] = pa | 2;172 }173 174 //40000000~80000000 -> 40000000~80000000175 for(va=0x40000000; va<0x80000000; va+=0x100000){176 pa = va;177 ttb[va >> 20] = pa | 2;178 }179 180 //30000000~40000000 -> 50000000~60000000181 for(va=0x30000000; va<0x40000000; va+=0x100000){182 pa = va + 0x20000000;183 ttb[va >> 20] = pa | 2;184 }185 }186 187 void enable_mmu(void)188 {189 unsigned long ttb = 0x70000000;190 init_ttb(ttb);191 unsigned long mmu = 0;192 mmu = 1 | (1 << 3) | (1 << 8);193 __asm__ __volatile__(194 "mov r0, #3\n"195 "mcr p15, 0, r0, c3, c0, 0\n" 196 "mcr p15, 0, %0, c2, c0, 0\n" 197 "mcr p15, 0, %1, c1, c0, 0\n" 198 :199 : "r" (ttb), "r" (mmu)200 );201 }202 203 void memcpy(unsigned char *dest, unsigned char *source, int len)204 {205 int i = 0;206 for(i=0; i<len; i++)207 dest[i] = source[i];208 }209 210 void led_on()211 {212 GPM4CON = 0x1111;213 GPM4DAT = 0;214 }215 216 void led_off()217 {218 GPM4CON = 0x1111;219 GPM4DAT = 0xf;220 }221 222 void wdt_on()223 {224 WTCON = 0 | (1 << 2) | (2 << 3) | (1 << 5) | (50 << 8);225 WTCNT = 0x8000;226 WTDAT = 0x8000;227 }228 229 void wdt_off()230 {231 WTCON = 0;232 }
第三十八天:Tiny4412驱动开发之外部中断
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。