首页 > 代码库 > 第三十八天: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) 
reg.h

 

 

 最后将看门狗中断和按键中断结合起来:实现按下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驱动开发之外部中断