zoukankan      html  css  js  c++  java
  • Crotex A9 中断流程

    Cortex A9 按键中断(SPI)流程

    示例: KEY2 中断控制点亮 LED2  

    【0】检测按键k2,按键k2按下一次,灯LED2闪一次。

    【1】查看原理图,连接引脚和控制逻辑
    (1)按键k2 连接在GPX1_1引脚
    (2)控制逻辑
           k2 按下  ---- K2闭合 ---- GPX1_1 低电压
           k2 常态  ---- K2打开 ---- GPX1_1 高电压

    【2】查看相应的芯片手册

        【2-1】循环检测GPX1_1引脚输入的电平,为低电压时,按键按下

            (1)配置GPX1_1引脚功能为输入,设置内部上拉下拉禁止。
                   GPX1.CON = GPX1.CON &(~(0xf<<4)) ;
       (2)循环检测 :  

     1 while(1)
     2 {
     3     if(!(GPX1.DAT & (0x1<<1)))  // 返回为真,按键按下
     4     {    
     5         msdelay(10);
     6         if(!(GPX1.DAT & (0x1<<1))) //二次检测,去抖
     7         {
     8             GPX2.DAT |= 0x1 << 7;  //Turn on LED2
     9             mydelay_ms(500);
    10             GPX2.DAT &= ~(0x1<<7);  //Turn off LED2
    11             mydelay_ms(500);
    12       
    13             while(!(GPX1.DAT & (0x1<<1)));
    14         }
    15     }
    16 }

           

       【2-2】中断方法检测按键
              将K2按下时,GPX1_1引脚获得的电平,作为异常事件。使能异常处理,k2每按下一次,响应一次异常处理。SPI 传递流程如下示:

         (1)外设一级 --- GPIO控制器
               0-- 将GPX1_1引脚的上拉和下拉禁止
                    GPX1PUD[3:2]= 0b00;

               1-- 将GPX1_1引脚功能设置为中断功能 WAKEUP_INT1[1] --- EXT_INT41[1]
                    GPX1CON[7:4] = 0xf

               2-- EXT_INT41CON  配置触发电平
                    当前配置成下降沿触发:
                    EXT_INT41CON[6:4] = 0x2

               3-- EXT_INT41_FLTCON0 配置中断引脚滤波
                    默认就是打开的,不需要配置

               4--EXT_INT41_MASK 中断使能寄存器
                    使能INT41[1]
                    EXT_INT41_MASK[1] = 0b0

               5--EXT_INT41_PEND 中断状态寄存器
                    当GPX1_1引脚接收到中断信号,中断发生,中断状态寄存器EXT_INT41_PEND 相应位会自动置1
                    注意:中断处理完成的时候,需要清除相应状态位。置1清0.
                    EXT_INT41_PEND[1] =0b1 
        (2)中断控制器

             0--找到外设中断名称和GIC中断控制器对应的名称

               查看芯片手册(本例:Exynos_4412 -- 9.2表)
                WAKEUP_INT1[1] --- EXT_INT41[1] --- INT[9] --- SPI[25]/ID[57]

             1--使能cpu0的spi25/id57
                ICDISER.ICDISER1 |= (0x1 << 25);    //57/32 =1...25 取整数(那个寄存器) 和余数(哪位)

             2--全局使能cpu0中断处理
                CPU0.ICCICR |= 0x1;

               3--优先级屏蔽寄存器,设置cpu0能处理所有的中断。
                  CPU0.ICCPMR = 0xFF;

               4--GIC使能 
                 ICDDCR =1;

               5--设置SPI[25]/ID[57]由那个cpu处理,当前设置为cpu0的irq中断
                   ICDIPTR.ICDIPTR14 |= 0x01<<8; //SPI25  interrupts are sent to processor 0   //57/4 = 14..1 14号寄存器的[15:8]

         (3)ARM内核(cpu0)


             1--四大步三小步 --- 硬件       

            (1)拷贝 CPSR 到 SPSR_<mode>
            (2)设置适当的 CPSR 位:                                
               (2-1)--改变处理器状态进入 ARM 态
               (2-2)--改变处理器模式进入相应的异常模式
               (2-3)--设置中断禁止位禁止相应中断 (如果需要)
            (3)保存返回地址到 LR_<mode>
            (4)设置 PC 为相应的异常向量
              2--中断服务程序 --- start.S 汇编
      1 .text
      2 .global _start
      3 _start:
      4         b        reset
      5         ldr        pc,_undefined_instruction
      6         ldr        pc,_software_interrupt
      7         ldr        pc,_prefetch_abort
      8         ldr        pc,_data_abort
      9         ldr        pc,_not_used
     10         ldr        pc,_irq
     11         ldr        pc,_fiq
     12 
     13 _undefined_instruction: .word  _undefined_instruction
     14 _software_interrupt:    .word  _software_interrupt
     15 _prefetch_abort:        .word  _prefetch_abort
     16 _data_abort:            .word  _data_abort
     17 _not_used:                .word  _not_used
     18 _irq:                    .word  irq_handler
     19 _fiq:                    .word  _fiq
     20 
     21 
     22 reset:
     23 
     24     ldr    r0,=0x40008000
     25     mcr    p15,0,r0,c12,c0,0        @ Vector Base Address Register
     26 
     27         mrs      r0,cpsr
     28         bic        r0,r0,#0x1f
     29         orr        r0,r0,#0xd3
     30         msr        cpsr,r0         @ Enable svc mode of cpu
     31 
     32         mov    r0, #0xfffffff
     33           mcr    p15, 0, r0, c1, c0, 2      @ Defines access permissions for each coprocessor
     34                                     @ Privileged and User mode access
     35 
     36     /*
     37      * Invalidate L1 I/D
     38      */
     39     mov    r0, #0            @ set up for MCR
     40     mcr    p15, 0, r0, c8, c7, 0    @ invalidate TLBs
     41     mcr    p15, 0, r0, c7, c5, 0    @ invalidate icache
     42 
     43 
     44     @Set the FPEXC EN bit to enable the FPU:
     45     MOV r3, #0x40000000
     46     fmxr FPEXC, r3
     47 
     48     /*
     49      * disable MMU stuff and caches
     50      */
     51     mrc    p15, 0, r0, c1, c0, 0
     52     bic    r0, r0, #0x00002000    @ clear bits 13 (--V-)
     53     bic    r0, r0, #0x00000007    @ clear bits 2:0 (-CAM)
     54     orr    r0, r0, #0x00001000    @ set bit 12 (---I) Icache
     55     orr    r0, r0, #0x00000002    @ set bit 1  (--A-) Align
     56     orr    r0, r0, #0x00000800    @ set bit 11 (Z---) BTB
     57     mcr    p15, 0, r0, c1, c0, 0
     58 
     59 /* LED Test Code */
     60 
     61     ldr r0, =0x114001E0
     62     ldr r1, [r0]
     63     bic r1, r1, #0xf0000
     64     orr r1, r1, #0x10000
     65     str r1, [r0]
     66 
     67     ldr r0, =0x114001E8
     68     ldr r1, [r0]
     69     bic r1, r1, #0x300
     70     str r1, [r0]
     71 
     72     ldr r0, =0x114001E4
     73     ldr r1, [r0]
     74     orr r1, r1, #0x10
     75     str r1, [r0]
     76 
     77 init_stack:
     78         ldr        r0,stacktop         /*get stack top pointer*/
     79 
     80     /********svc mode stack********/
     81         mov        sp,r0
     82         sub        r0,#128*4          /*512 byte  for irq mode of stack*/
     83     /****irq mode stack**/
     84         msr        cpsr,#0xd2
     85         mov        sp,r0
     86         sub        r0,#128*4          /*512 byte  for irq mode of stack*/
     87     /***fiq mode stack***/
     88         msr     cpsr,#0xd1
     89         mov        sp,r0
     90         sub        r0,#0
     91     /***abort mode stack***/
     92         msr        cpsr,#0xd7
     93         mov        sp,r0
     94         sub        r0,#0
     95     /***undefine mode stack***/
     96         msr        cpsr,#0xdb
     97         mov        sp,r0
     98         sub        r0,#0
     99    /*** sys mode and usr mode stack ***/
    100         msr        cpsr,#0x10
    101         mov        sp,r0             /*1024 byte  for user mode of stack*/
    102 
    103         b        main
    104 
    105     .align    4
    106 
    107     /****  swi_interrupt handler  ****/
    108 
    109 
    110     /****  irq_handler  ****/
    111 irq_handler:
    112 
    113     sub  lr,lr,#4
    114     stmfd sp!,{r0-r12,lr}
    115     .weak do_irq
    116     bl    do_irq
    117     ldmfd sp!,{r0-r12,pc}^
    118 
    119 stacktop:    .word         stack+4*512
    120 .data
    121 
    122 stack:     .space  4*512
    start.S

                   3--中断处理程序 --- do_irq函数 c语言(函数原型void name(void))
                     (1) 读取正在处理的中断ID寄存器(ICCIAR)
                     irq_num = (CPU0.ICCIAR & 0x1FF);
                   (2)根据irq_num,分支处理中断
                   (3)清除中断状态位 
                        (3-1)i.外设级,EXT_INT41_PEND |= 0x1 << 1;
                        (3-2)ii.GIC级,ICDICPR.ICDICPR1 |= 0x1 << 25;
                        (3-3)iii.CPU0级 CPU0.ICCEOIR = (CPU0.ICCEOIR & ~(0x1FF)) | irq_num;

    C代码:

     1 #include "exynos_4412.h"
     2 
     3 void mydelay_ms(int ms)
     4 {
     5     int i, j;
     6     while(ms--)
     7     {
     8         for (i = 0; i < 5; i++)
     9             for (j = 0; j < 514; j++);
    10     }
    11 }
    12 
    13 void do_irq(void )
    14 {
    15     int irq_num;
    16     irq_num = (CPU0.ICCIAR & 0x1FF);
    17     switch (irq_num) {
    18 
    19     case 57: //
    20         //Clear Pend
    21         EXT_INT41_PEND |= 0x1 << 1;
    22         ICDICPR.ICDICPR1 |= 0x1 << 25;
    23 
    24         //Turn on LED2
    25         GPX2.DAT |= 0x1 << 7;
    26         mydelay_ms(500);
    27 
    28         //Turn off LED2
    29         GPX2.DAT &= ~(0x1 << 7);
    30         mydelay_ms(500);
    31 
    32 
    33         break;
    34     }
    35 
    36     // End of interrupt
    37     CPU0.ICCEOIR = (CPU0.ICCEOIR & ~(0x1FF)) | irq_num;
    38 
    39 }
    40 
    41 
    42 int main(void)
    43 {
    44     GPX2.CON = (GPX2.CON & ~(0xf << 28)) | 1 << 28; //GPX2_7:output, LED2
    45 
    46     //Key_2  Interrupt  GPX1_1
    47     GPX1.PUD = GPX1.PUD & ~(0x3 << 2); // Disables Pull-up/Pull-down
    48     GPX1.CON = (GPX1.CON & ~(0xF << 4)) | (0xF << 4); //GPX1_1: WAKEUP_INT1[1](EXT_INT41[1])
    49     EXT_INT41_CON = (EXT_INT41_CON & ~(0x7 << 4)) | 0x2 << 4;
    50     EXT_INT41_MASK = (EXT_INT41_MASK & ~(0x1 << 1)); //  Bit: 0 = Enables interrupt
    51 
    52      //* GIC interrupt controller:
    53 
    54     // Enables the corresponding interrupt SPI25-- Key_2
    55     ICDISER.ICDISER1 |= (0x1 << 25);
    56     CPU0.ICCICR |= 0x1; //Global enable for signaling of interrupts
    57     CPU0.ICCPMR = 0xFF; //The priority mask level.Priority filter. threshold
    58     ICDDCR = 1; //Bit0:  GIC global enable
    59 
    60     ICDIPTR.ICDIPTR14 |= 0x01<<8; //SPI25  interrupts are sent to processor 0
    61 
    62 
    63     while (1);
    64 
    65     return 0;
    66 }
  • 相关阅读:
    Spire.Barcode好用的条码生在组件
    jQuery、js操作页面
    设计模式---简介
    设计模式---策略设计模式
    POI生成Excel文件:Excel,工具类,背景色,边框,居中,合并单元格
    设计模式---模板设计模式(java)
    maven打包不打lib目录里面的jar包解决办法
    MySQL库表操作
    Linux环境根据data目录文件恢复MySQL数据
    Linux 安装 mysql 与 mysql在Linux环境本地使用,但windows远程连不了问题处理
  • 原文地址:https://www.cnblogs.com/Je-Cortex/p/4840615.html
Copyright © 2011-2022 走看看