www.mikrocontroller.net

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


Autor: Andreas N. (poolspieler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich kämpfe mich gerade durch die Interruptbehandlung des MicroBlaze im 
XPS durch.
#include <xintc_l.h>
#include <xgpio.h>
#include <xparameters.h>
#include <xintc.h>

 
XGpio gpio_ausgang;
XGpio gpio_eingang1;
XGpio gpio_eingang2;
XIntc mein_interrupt;

int eventcounter1 = 0;
int eventcounter2 = 0;

void int_handler1(void * baseaddr_p) {
  eventcounter1++;
  xil_printf("INT1 counter=%d Zustand=%d\r\n", eventcounter1, XGpio_DiscreteRead(&gpio_eingang1, 1));
  XGpio_InterruptClear(&gpio_eingang1, XPAR_XPS_GPIO_EINGANG_IP2INTC_IRPT_MASK);
}

void int_handler2(void * baseaddr_p) {
  eventcounter2++;
  xil_printf("INT2 counter=%d Zustand=%d\r\n", eventcounter2, XGpio_DiscreteRead(&gpio_eingang2, 1));
  XGpio_InterruptClear(&gpio_eingang2, XPAR_XPS_GPIO_EINGANG2_IP2INTC_IRPT_MASK);
}

int main() {
  int i;
  
  XIntc_Initialize(&mein_interrupt, XPAR_INTC_SINGLE_DEVICE_ID);

  XIntc_Connect(&mein_interrupt,
                             XPAR_XPS_INTC_0_XPS_GPIO_EINGANG2_IP2INTC_IRPT_INTR,
                             (XInterruptHandler) int_handler2,
                             (void *)XPAR_XPS_GPIO_EINGANG2_BASEADDR);
  XIntc_Connect(&mein_interrupt,
                             XPAR_XPS_INTC_0_XPS_GPIO_EINGANG_IP2INTC_IRPT_INTR,
                             (XInterruptHandler) int_handler1,
                             (void *)XPAR_XPS_GPIO_EINGANG_BASEADDR);
  /* Register the Timer interrupt handler in the vector table */
/*--> so hab ichs auch mal probiert - gleiches Verhalten...
  XIntc_RegisterHandler(XPAR_XPS_INTC_0_BASEADDR,
                             XPAR_XPS_INTC_0_XPS_GPIO_EINGANG2_IP2INTC_IRPT_INTR,
                             (XInterruptHandler) int_handler2,
                             (void *)XPAR_XPS_GPIO_EINGANG2_BASEADDR);
*/
  /* Register the Timer interrupt handler in the vector table */
/*  XIntc_RegisterHandler(XPAR_XPS_INTC_0_BASEADDR,
                             XPAR_XPS_INTC_0_XPS_GPIO_EINGANG_IP2INTC_IRPT_INTR,
                             (XInterruptHandler) int_handler1,
                             (void *)XPAR_XPS_GPIO_EINGANG_BASEADDR);
*/
  /* Initialize and set the direction of the GPIO connected to LEDs */
  XGpio_Initialize(&gpio_ausgang, XPAR_XPS_GPIO_AUSGANG_DEVICE_ID);
  XGpio_SetDataDirection(&gpio_ausgang,1, 0);

  XGpio_Initialize(&gpio_eingang1, XPAR_XPS_GPIO_EINGANG_DEVICE_ID);
  XGpio_SetDataDirection(&gpio_eingang1,1, 1);

  XGpio_Initialize(&gpio_eingang2, XPAR_XPS_GPIO_EINGANG2_DEVICE_ID);
  XGpio_SetDataDirection(&gpio_eingang2,1, 1);

  /* Start the interrupt controller */
  XIntc_Enable(&mein_interrupt, XPAR_XPS_INTC_0_XPS_GPIO_EINGANG_IP2INTC_IRPT_INTR);
  XIntc_Enable(&mein_interrupt, XPAR_XPS_INTC_0_XPS_GPIO_EINGANG2_IP2INTC_IRPT_INTR);
  XIntc_mMasterEnable(XPAR_XPS_INTC_0_BASEADDR);
//  XIntc_mEnableIntr(XPAR_XPS_INTC_0_BASEADDR, XPAR_XPS_GPIO_EINGANG_IP2INTC_IRPT_MASK | XPAR_XPS_GPIO_EINGANG2_IP2INTC_IRPT_MASK);
//  XIntc_mEnableIntr(XPAR_XPS_INTC_0_BASEADDR, 0xFFFFFFFF);

  XGpio_InterruptEnable(&gpio_eingang1, XPAR_XPS_GPIO_EINGANG_IP2INTC_IRPT_MASK);
  XGpio_InterruptGlobalEnable(&gpio_eingang1);
  XGpio_InterruptClear(&gpio_eingang1, XPAR_XPS_GPIO_EINGANG_IP2INTC_IRPT_MASK);
  
  XGpio_InterruptEnable(&gpio_eingang2, XPAR_XPS_GPIO_EINGANG2_IP2INTC_IRPT_MASK);
  XGpio_InterruptGlobalEnable(&gpio_eingang2);
  XGpio_InterruptClear(&gpio_eingang2, XPAR_XPS_GPIO_EINGANG2_IP2INTC_IRPT_MASK);

  xil_printf("START\r\n");
  
  /* Enable MicroBlaze Interrupts */
  microblaze_enable_interrupts();

  /* Wait for interrupts to occur */
  while(1) { 
    for(i=0; i<5000000; i++)
      ;
    xil_printf("main(): Zustand1=%d Zustand1=%d\r\n", XGpio_DiscreteRead(&gpio_eingang1, 1), XGpio_DiscreteRead(&gpio_eingang2, 1));
  }
}

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.... 
hat das selbe Problem - nur auch keine Lösung...

Gruß,
Andreas

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.