Forum: FPGA, VHDL & Co. Interrupt Controller funktioniert nur für den ersten INT0


von Andreas N. (poolspieler)


Lesenswert?

Hallo,
ich kämpfe mich gerade durch die Interruptbehandlung des MicroBlaze im 
XPS durch.
1
#include <xintc_l.h>
2
#include <xgpio.h>
3
#include <xparameters.h>
4
#include <xintc.h>
5
6
 
7
XGpio gpio_ausgang;
8
XGpio gpio_eingang1;
9
XGpio gpio_eingang2;
10
XIntc mein_interrupt;
11
12
int eventcounter1 = 0;
13
int eventcounter2 = 0;
14
15
void int_handler1(void * baseaddr_p) {
16
  eventcounter1++;
17
  xil_printf("INT1 counter=%d Zustand=%d\r\n", eventcounter1, XGpio_DiscreteRead(&gpio_eingang1, 1));
18
  XGpio_InterruptClear(&gpio_eingang1, XPAR_XPS_GPIO_EINGANG_IP2INTC_IRPT_MASK);
19
}
20
21
void int_handler2(void * baseaddr_p) {
22
  eventcounter2++;
23
  xil_printf("INT2 counter=%d Zustand=%d\r\n", eventcounter2, XGpio_DiscreteRead(&gpio_eingang2, 1));
24
  XGpio_InterruptClear(&gpio_eingang2, XPAR_XPS_GPIO_EINGANG2_IP2INTC_IRPT_MASK);
25
}
26
27
int main() {
28
  int i;
29
  
30
  XIntc_Initialize(&mein_interrupt, XPAR_INTC_SINGLE_DEVICE_ID);
31
32
  XIntc_Connect(&mein_interrupt,
33
                             XPAR_XPS_INTC_0_XPS_GPIO_EINGANG2_IP2INTC_IRPT_INTR,
34
                             (XInterruptHandler) int_handler2,
35
                             (void *)XPAR_XPS_GPIO_EINGANG2_BASEADDR);
36
  XIntc_Connect(&mein_interrupt,
37
                             XPAR_XPS_INTC_0_XPS_GPIO_EINGANG_IP2INTC_IRPT_INTR,
38
                             (XInterruptHandler) int_handler1,
39
                             (void *)XPAR_XPS_GPIO_EINGANG_BASEADDR);
40
  /* Register the Timer interrupt handler in the vector table */
41
/*--> so hab ichs auch mal probiert - gleiches Verhalten...
42
  XIntc_RegisterHandler(XPAR_XPS_INTC_0_BASEADDR,
43
                             XPAR_XPS_INTC_0_XPS_GPIO_EINGANG2_IP2INTC_IRPT_INTR,
44
                             (XInterruptHandler) int_handler2,
45
                             (void *)XPAR_XPS_GPIO_EINGANG2_BASEADDR);
46
*/
47
  /* Register the Timer interrupt handler in the vector table */
48
/*  XIntc_RegisterHandler(XPAR_XPS_INTC_0_BASEADDR,
49
                             XPAR_XPS_INTC_0_XPS_GPIO_EINGANG_IP2INTC_IRPT_INTR,
50
                             (XInterruptHandler) int_handler1,
51
                             (void *)XPAR_XPS_GPIO_EINGANG_BASEADDR);
52
*/
53
  /* Initialize and set the direction of the GPIO connected to LEDs */
54
  XGpio_Initialize(&gpio_ausgang, XPAR_XPS_GPIO_AUSGANG_DEVICE_ID);
55
  XGpio_SetDataDirection(&gpio_ausgang,1, 0);
56
57
  XGpio_Initialize(&gpio_eingang1, XPAR_XPS_GPIO_EINGANG_DEVICE_ID);
58
  XGpio_SetDataDirection(&gpio_eingang1,1, 1);
59
60
  XGpio_Initialize(&gpio_eingang2, XPAR_XPS_GPIO_EINGANG2_DEVICE_ID);
61
  XGpio_SetDataDirection(&gpio_eingang2,1, 1);
62
63
  /* Start the interrupt controller */
64
  XIntc_Enable(&mein_interrupt, XPAR_XPS_INTC_0_XPS_GPIO_EINGANG_IP2INTC_IRPT_INTR);
65
  XIntc_Enable(&mein_interrupt, XPAR_XPS_INTC_0_XPS_GPIO_EINGANG2_IP2INTC_IRPT_INTR);
66
  XIntc_mMasterEnable(XPAR_XPS_INTC_0_BASEADDR);
67
//  XIntc_mEnableIntr(XPAR_XPS_INTC_0_BASEADDR, XPAR_XPS_GPIO_EINGANG_IP2INTC_IRPT_MASK | XPAR_XPS_GPIO_EINGANG2_IP2INTC_IRPT_MASK);
68
//  XIntc_mEnableIntr(XPAR_XPS_INTC_0_BASEADDR, 0xFFFFFFFF);
69
70
  XGpio_InterruptEnable(&gpio_eingang1, XPAR_XPS_GPIO_EINGANG_IP2INTC_IRPT_MASK);
71
  XGpio_InterruptGlobalEnable(&gpio_eingang1);
72
  XGpio_InterruptClear(&gpio_eingang1, XPAR_XPS_GPIO_EINGANG_IP2INTC_IRPT_MASK);
73
  
74
  XGpio_InterruptEnable(&gpio_eingang2, XPAR_XPS_GPIO_EINGANG2_IP2INTC_IRPT_MASK);
75
  XGpio_InterruptGlobalEnable(&gpio_eingang2);
76
  XGpio_InterruptClear(&gpio_eingang2, XPAR_XPS_GPIO_EINGANG2_IP2INTC_IRPT_MASK);
77
78
  xil_printf("START\r\n");
79
  
80
  /* Enable MicroBlaze Interrupts */
81
  microblaze_enable_interrupts();
82
83
  /* Wait for interrupts to occur */
84
  while(1) { 
85
    for(i=0; i<5000000; i++)
86
      ;
87
    xil_printf("main(): Zustand1=%d Zustand1=%d\r\n", XGpio_DiscreteRead(&gpio_eingang1, 1), XGpio_DiscreteRead(&gpio_eingang2, 1));
88
  }
89
}

Im obigen Code wird nur int_handler1() aufgerufen wenn sich die 
jeweiligen Eingänge ändern.
int_handler2() wird nicht aufgerufen.
Wenn ich allerdings die Priorität der Interrupts im 
EDK-->SystemAssemblyView-->Ports-->xps_intc0-->Intr vertausche, dann 
wird auf einmal int_handler2() korrekt ausgeführt und int_handler1() 
NICHT MEHR!!!???!!!

Hat jemand eine Idee, an was das liegen kann? Mir fällt nix mehr ein... 
:-((

Ich denke, die Dame hier: 
http://forums.xilinx.com/xlnx/board/message?board.id=Spartan&message.id=632 
hat das selbe Problem - nur auch keine Lösung...

Gruß,
Andreas

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.