×
单片机 > 单片机程序设计 > 详情

Tiny4412中断控制器(GIC)之外部中断

发布时间:2020-05-22 发布时间:
|

#include "regs.h"

void enable_mmu(unsigned long ttb);

void init_ttb(unsigned long *ttb_base);

void mmap(unsigned long *ttb_base, unsigned long va, unsigned long pa);

void memset(char *buf, char ch, int size);

void memcpy(char *dst, char *src, int size);

void do_irq(unsigned long regs[]);

void (*printf)(char *, ...) = 0x43e11434;

void main(void)

{    

    unsigned long  vector_base = 0xffff0000;

    unsigned long  tt_base = 0x73000000;

    unsigned long *pdo_irq = 0x75000000;

    extern unsigned long vectors_start, vectors_end;

    memset(tt_base, 0x00, 16 * 1024);

    mmap(tt_base, vector_base, 0x70000000);    

    enable_mmu(tt_base);

    memcpy(vector_base, vectors_start, 0x100);

    *pdo_irq = do_irq;

    

    //让cpu开中断,cpu可以接收中断,要关闭cpu的中断用cpsid

    //一条指令就可以完成对特殊功能寄存器的写操作,以前代码:

    //mrs r0,cpsr

    //bic r0,r0,#0x80  //清掉最高位

    //msr cpsr,r0

    __asm__ __volatile__ (

        "cpsie i "

    );

    //-------------------------------------------------------------------------

    // 使能GIC中断

    ICCICR_CPU0 = 1;

    ICCPMR_CPU0 =  0xff;  // Priority Unmask All Interrupt

    //------------ Eint26 for K1 irqID is 64----------------- 

    ICDDCR = 1;

    // 64号中断优先级,the Zero is Highest priority

    // 该寄存器中每个中断号占8位,64号中断就在ICDIPTR16寄存器当中

    ICDIPR16_CPU0 = ~(0xff << 0);

    

    // 64号中断给哪个cpu发,该寄存器中每个中断号占8位,64号中断就在ICDIPTR16寄存器当中

    // 给cpu0发在ICDIPTR16_CPU0寄存器里面要写上,for CPU0, refer PG815

    // 如果给cpu1、cpu3两个发既要在ICDIPTR16_CPU0上写上也要在ICDIPTR16_CPU3上写入

    ICDIPTR16_CPU0 = (1 << 0);   

    

    // enable interrupt 0,每个中断号占一位,64号中断在ICDISER2当中

    ICDISER2_CPU0 = (1 << 0);

    //-------------------------------------------------------------------------

    

    //使能外部中断控制器,设置中断引脚;内部中断不用这些设置(timer,watchdog中断等)

    GPX3CON  &= ~(0x7 << 8);

    GPX3CON  |=  (0xf << 8);  //Configure as Exint43_2 --- EINT26

    EXT_INT43CON  &=  ~(0x7 << 8);

    EXT_INT43CON  &=  ~(0x3 << 8); //设置触发边沿:rising edge

    

    EXT_INT43_MASK &= ~(0x1 << 2); //enable ExtINT43_2 --- EINT26 for K1

}

void do_irq(unsigned long regs[])

{

    if (EXT_INT43_PEND & (1 << 2)) {  //产看是不是发生中断

        printf("ExtInt43_2 ");    

        EXT_INT43_PEND |= (1 << 2);      //清除中断

    }

}

void enable_mmu(unsigned long ttb)

{    

    unsigned long c1_flags;

    init_ttb(ttb);

    c1_flags = 1 | (1 << 3) | ( 1 << 11) | ( 1 << 13) |  (1 << 28);

    __asm__ __volatile__ (

        "mvn r0, #0 "            

        "mcr p15, 0, r0, c3, c0, 0 "

        "mcr p15, 0, %1, c2, c0, 0 " //configure ttb

        "mrc p15, 0, r0, c1, c0, 0 "

        "orr %0, r0, %0 "

        "mcr p15, 0, %0, c1, c0, 0 " //enable mmu

        :

        : "r" (c1_flags), "r" (ttb)

        : "r0"

    );

}

void init_ttb(unsigned long *ttb_base)

{

    unsigned long va, pa;

    for (va = 0x00000000; va < 0x10000000; va += 0x100000) { //Others

        pa = va;

        ttb_base[ va >> 20] = (pa & 0xfff00000) | 2;    

    }

    for (va = 0x10000000; va < 0x14000000; va += 0x100000) { //SFR

        pa = va;

        ttb_base[ va >> 20] = (pa & 0xfff00000) |  2;    

    }

    for (va = 0x40000000; va < 0x80000000; va += 0x100000) { //DRAM

        pa = va;

        ttb_base[ va >> 20] = (pa & 0xfff00000) | 2;    

    }

}

void mmap(unsigned long *ttb_base, unsigned long va, unsigned long pa)

{

    ttb_base[ va >> 20] = (pa & 0xfff00000) |  2;    

}

void memset(char *buf, char ch, int size)

{

    int i;

    for (i = 0; i < size; i ++)

        buf[i] = ch;

}

void memcpy(char *dst, char *src, int size)

{

    int i;

    for (i = 0; i < size; i ++) 

        dst[i] = src[i];    

}

__asm__ (

"vectors: "

    "b reset "

    "b und "

    "b swi "

    "b pre_abt "

    "b dat_abt "

    ".word 0 "

    "b irq "

    "b fiq "

"reset: "

"und: "

    "mov sp, #0x74000000 "

    "stmfd sp!, {r0-r12, lr} "

    "mov r0, sp "

    "mov r3, #0x74000000 "

    "ldr r3, [r3] "

    "blx r3 "

    "mov sp, #0x74000000 "

    "ldmea sp, {r0-r12, pc}^ "

"swi: "

"pre_abt: "

"dat_abt: "

"fiq: "

"irq: "

    "mov sp, #0x75000000 "

    "sub lr, lr, #4     "

    "stmfd sp!, {r0-r12, lr} "

    

    "mov r0, sp "

    "mov r3, #0x75000000 "

    "ldr r3, [r3] "

    "blx r3 "

    "mov sp, #0x75000000 "

    "ldmea sp, {r0-r12, pc}^ "

"EOV: "

"vectors_start: "

    ".word vectors "

"vectors_end: "

    ".word EOV "

);

===================================================================

Makefile文件:

default:

    arm-linux-gcc -c test.c  -o test.o

    arm-linux-ld  -Ttext=0x70003000  test.o  -o test

    arm-linux-objcopy  -O binary  test  test.bin

clean:

    rm -f test.o  test  test.bin   *~ 

===============================================================


关键字:Tiny4412  中断控制器  GIC  外部中断 

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
51单片机中断源的扩展方法