2014-10-25 5 views
3

У меня простой микроблог с двумя Gpio (кнопка и переключатели) Я хочу, чтобы оба устройства прерывали. Вот код, но не работает.Многократный код прерывания Microblaze не работает

#include<xparameters.h> 
#include<xgpio.h> 
#include<xintc.h> 
#include<xil_exception.h> 

static XGpio PushBt; 
static XGpio sw; 
static XIntc myIntc; 
int delay, limit=3000000; 

void pb_int_handler(void *baseaddr_p) { 
     Xuint32 dsr; 

     //DSR contains the INFORMATION of which button was depressed, so we can switch 
     //on its value. 
     dsr = XGpio_DiscreteRead(&PushBt, 1); 
     switch(dsr) { 

      case 0x01: 
       xil_printf("Up\r\n"); 
       for(delay=0;delay<limit;delay++){}; // delay cycle 
       break; 

      case 0x02: 
       xil_printf("Left\r\n"); 
       for(delay=0;delay<limit;delay++){}; // delay cycle 
       break; 

      case 0x08: 
       xil_printf("Right\r\n"); 
       for(delay=0;delay<limit;delay++){}; // delay cycle 
       break; 

      case 0x04: 
       xil_printf("Down\r\n"); 
       for(delay=0;delay<limit;delay++){}; // delay cycle 
       break; 

      default : {} 

     } 
     //Clear the interrupt both in the Gpio instance as well as the interrupt controller 
     XGpio_InterruptClear(&PushBt, 0x3); 
     XIntc_Acknowledge(&myIntc,XPAR_AXI_INTC_0_PUSH_IP2INTC_IRPT_INTR); 
    } 

void sw_int_handler(void *baseaddr_p) { 
     Xuint32 dsr; 

     //DSR contains the INFORMATION of which button was depressed, so we can switch 
     //on its value. 
     dsr = XGpio_DiscreteRead(&sw, 1); 
     switch(dsr) { 

      case 0x00: 
       xil_printf("Switches 00 \r\n"); 
       for(delay=0;delay<limit;delay++){}; // delay cycle 
       break; 

      case 0x01: 
       xil_printf("Switches 01 \r\n"); 
       for(delay=0;delay<limit;delay++){}; // delay cycle 
       break; 

      case 0x02: 
       xil_printf("Switches 02 \r\n"); 
       for(delay=0;delay<limit;delay++){}; // delay cycle 
       break; 

      case 0x03: 
       xil_printf("Switches 03 \r\n"); 
       for(delay=0;delay<limit;delay++){}; // delay cycle 
       break; 

      default : {} 

     } 
     //Clear the interrupt both in the Gpio instance as well as the interrupt controller 
     XGpio_InterruptClear(&sw, 0x3); 
     XIntc_Acknowledge(&myIntc,XPAR_AXI_INTC_0_SW_IP2INTC_IRPT_INTR); 
    } 

int main(void) { 

    xil_printf("Setting up peripherals...\r\n"); 
    for(delay=0;delay<limit;delay++){}; // delay cycle 

    xil_printf("Setting up push buttons...\r\n"); 
    for(delay=0;delay<limit;delay++){}; // delay cycle 

     XGpio_Initialize(&PushBt, XPAR_PUSH_DEVICE_ID); 
     XGpio_SetDataDirection(&PushBt,1,1); //set pb as input port 
     XGpio_InterruptEnable(&PushBt, XPAR_PUSH_IP2INTC_IRPT_MASK); 
     XGpio_InterruptGlobalEnable(&PushBt); 

    xil_printf("Setting up switches...\r\n"); 
    for(delay=0;delay<limit;delay++){}; // delay cycle 

     XGpio_Initialize(&sw, XPAR_SW_DEVICE_ID); 
     XGpio_SetDataDirection(&sw,1,1); //set sw as input port 
     XGpio_InterruptEnable(&sw, XPAR_SW_IP2INTC_IRPT_MASK); 
     XGpio_InterruptGlobalEnable(&sw); 

    xil_printf("Setting up interrupt controller...\r\n"); 
    for(delay=0;delay<limit;delay++){}; // delay cycle 
    XIntc_Initialize(&myIntc, XPAR_INTC_0_DEVICE_ID); 

    xil_printf("Register the interrupt...\r\n"); 
    for(delay=0;delay<limit;delay++){}; // delay cycle 
    XIntc_Connect(&myIntc, XPAR_AXI_INTC_0_PUSH_IP2INTC_IRPT_INTR, 
           (XInterruptHandler)pb_int_handler, 
            &PushBt); 
    XIntc_Connect(&myIntc, XPAR_AXI_INTC_0_SW_IP2INTC_IRPT_INTR, 
            (XInterruptHandler)sw_int_handler, 
             &sw); 

    xil_printf("Enable individual interrupt...\r\n"); 
    for(delay=0;delay<limit;delay++){}; // delay cycle 
    XIntc_EnableIntr(&myIntc,XPAR_PUSH_IP2INTC_IRPT_MASK | XPAR_SW_IP2INTC_IRPT_MASK); 

    xil_printf("Start the interrupt controller...\r\n"); 
    for(delay=0;delay<limit;delay++){}; // delay cycle 
    XIntc_Start(&myIntc, XIN_REAL_MODE); 
    XIntc_MasterEnable(&myIntc); 
    microblaze_enable_interrupts(); 

    xil_printf("Setting up exceptions...\r\n"); 
    for(delay=0;delay<limit;delay++){}; // delay cycle 
    Xil_ExceptionInit(); 

    Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_M_AXI_I_EXCEPTION, 
      (XExceptionHandler)XIntc_InterruptHandler, 
         &myIntc); 
    Xil_ExceptionEnable(); 

    while(1) { 
     xil_printf("Entering loop...\r\n"); 
     for(delay=0;delay<limit;delay++){}; // delay cycle 
    } 
} 

Любая помощь, объясняющая правильную последовательность кода прерывания? Я настраиваю обработчики. Я инициализирую контроллер прерывания. Я подключаю обработчики. Я включил маски прерывания. Включить мастер. Я запускаю контроллер.

Итак, что я забыл? Или что случилось? Благодарности

+0

для записи: я нахожу и insterestng документов по Xilinx «Использование и создание системы прерываний на основе» в два verison 2005 и 2009 (ver3_4) Я помог, что помощь – Gian

+0

найдено решение: изменение этих строк XGpio_InterruptEnable (& PushBt, XPAR_PUSH_IP2INTC_IRPT_MASK); к XGpio_InterruptEnable (& PushBt, 0xff); и XGpio_InterruptEnable (& sw, XPAR_SW_IP2INTC_IRPT_MASK); к XGpio_InterruptEnable (& sw, 0xff); так что теперь работает код, но я буду исследовать, почему :) Это проблема маски прерывания. – Gian

+0

Вы можете ответить на свой собственный пост и принять его, чтобы он больше не был помечен как «без ответа» – Coconop

ответ

0

найдено решение: изменение этих линий

XGpio_InterruptEnable(&PushBt, XPAR_PUSH_IP2INTC_IRPT_MASK); 

в

XGpio_InterruptEnable(&PushBt, 0xff); 

и

XGpio_InterruptEnable(&sw, XPAR_SW_IP2INTC_IRPT_MASK); 

в

XGpio_InterruptEnable(&sw, 0xff); 

так что теперь код работает, но я буду исследовать, почему :) Это проблема маски прерывания