Forum: FPGA, VHDL & Co. xil GPIO 2x Interrupt


von olpo (Gast)


Lesenswert?

Halli hallo,

ich benutze xGPIO um mit den Druckknöpfen an meinem FPGA-Board einen 
Interrupt in C zu generieren.

Das klappt auch.

Jetzt möchte ich jedoch für alle vier Druckknöpfe unterschiedliche 
Interrupts erzeugen, und das funktioniert noch nicht.

Ich habe versucht, alle vier Druckknöpfe über einen GPIO-Core 
anzusprechen.
Die Frage ist jetzt, geht das so, oder brauche ich für jeden Druckknopf 
einen eigenen GPIO?

Hier ist mal der .mhs und .ucf Code.
1
#system.mhs
2
3
PORT Push_Buttons_GPIO_0_IO_pin = Push_Buttons_GPIO_0_IO, DIR = IO, VEC = [0:1]
4
PORT Push_Buttons_GPIO_1_IO_pin = Push_Buttons_GPIO_1_IO, DIR = IO, VEC = [0:1]
5
6
BEGIN xps_gpio
7
 PARAMETER INSTANCE = Push_Buttons
8
 PARAMETER HW_VER = 2.00.a
9
 PARAMETER C_INTERRUPT_PRESENT = 1
10
 PARAMETER C_BASEADDR = 0x00040000
11
 PARAMETER C_HIGHADDR = 0x000401FF
12
 PARAMETER C_GPIO_WIDTH = 2
13
 PARAMETER C_IS_DUAL = 1
14
 PARAMETER C_GPIO2_WIDTH = 2
15
 BUS_INTERFACE SPLB = mb_plb
16
 PORT GPIO_0_IO = Push_Buttons_GPIO_0_IO
17
 PORT IP2INTC_Irpt = Push_Buttons_IP2INTC_Irpt
18
 PORT GPIO_1_IO = Push_Buttons_GPIO_1_IO
19
END
1
# West
2
Net Push_Buttons_GPIO_0_IO_pin<0> LOC = AJ7  |  IOSTANDARD=LVCMOS33  |  PULLDOWN  |  SLEW=SLOW  |  DRIVE=2;
3
# East
4
Net Push_Buttons_GPIO_0_IO_pin<1> LOC = AK7  |  IOSTANDARD=LVCMOS33  |  PULLDOWN  |  SLEW=SLOW  |  DRIVE=2;
5
# South
6
Net Push_Buttons_GPIO_1_IO_pin<0> LOC = V8  |  IOSTANDARD=LVCMOS33  |  PULLDOWN  |  SLEW=SLOW  |  DRIVE=2;
7
# North
8
Net Push_Buttons_GPIO_1_IO_pin<1> LOC = U8  |  IOSTANDARD=LVCMOS33  |  PULLDOWN  |  SLEW=SLOW  |  DRIVE=2;

Ich kann im C-Code aber immer nur Knopf "West" ansprechen.
Bzw. ich weiß schlicht und einfach nicht wie ich die anderen ansprechen 
soll.

Die xparameters.h liefert diese Parameter:
1
/* Definitions for driver GPIO */
2
#define XPAR_XGPIO_NUM_INSTANCES 1
3
4
/* Definitions for peripheral PUSH_BUTTONS */
5
#define XPAR_PUSH_BUTTONS_BASEADDR 0x00040000
6
#define XPAR_PUSH_BUTTONS_HIGHADDR 0x000401FF
7
#define XPAR_PUSH_BUTTONS_DEVICE_ID 0
8
#define XPAR_PUSH_BUTTONS_INTERRUPT_PRESENT 1
9
#define XPAR_PUSH_BUTTONS_IS_DUAL 1
10
11
#define XPAR_INTC_0_GPIO_0_VEC_ID XPAR_XPS_INTC_PUSH_BUTTONS_IP2INTC_IRPT_INTR

Es sind also keine Parameter für die einzelnen Druckknöpfe gegeben.

Und hier ist der C-Code für den einen Druckknopf.
Auch hier sehe ich nicht, wie ich andere Knöpfe ansprechen soll.
1
XGpio gpio_PUSH;
2
3
void meine_Routine(){
4
...
5
}
6
7
/**
8
 *  Initialize GPIO Interrupt
9
 */
10
int GpioSetupIntrSystem (XIntc *IntcInstancePtr, XGpio *InstancePtr,
11
    u16 DeviceId, u16 IntrId, u16 IntrMask) {
12
13
  int Status;
14
15
  /* Hook up interrupt service routine */
16
  Status = XIntc_Connect(IntcInstancePtr, IntrId,
17
      (XInterruptHandler) meine_Routine, InstancePtr);
18
  if (Status != XST_SUCCESS) {
19
    return XST_FAILURE;
20
  }
21
22
  /* Enable the interrupt vector at the interrupt controller */
23
  XIntc_Enable(IntcInstancePtr, IntrId);
24
25
  /*
26
   * Enable the GPIO channel interrupts so that push button can be
27
   * detected and enable interrupts for the GPIO device
28
   */
29
  XGpio_InterruptEnable(InstancePtr, IntrMask);
30
  XGpio_InterruptGlobalEnable(InstancePtr);
31
32
  return XST_SUCCESS;
33
}
34
35
36
int main() 
37
{
38
   int Status;
39
   static XIntc InterruptController;
40
41
   XGpio_Initialize(&gpio_PUSH, XPAR_PUSH_BUTTONS_DEVICE_ID);
42
43
   /*
44
    * Initialize the interrupt controller driver so that it's ready to use.
45
    * specify the device ID that was generated in xparameters.h
46
    */
47
   Status = XIntc_Initialize( &InterruptController,
48
XPAR_XPS_INTC_DEVICE_ID);
49
  if (Status != XST_SUCCESS) {
50
    return XST_FAILURE;
51
  }
52
   /* set Push-Button Interrupt */
53
   Status = GpioSetupIntrSystem(&InterruptController, &gpio_PUSH, XPAR_PUSH_BUTTONS_DEVICE_ID,
54
      XPAR_INTC_0_GPIO_1_VEC_ID, 1);
55
56
  /*
57
   * Start the interrupt controller such that interrupts are recognized
58
   * and handled by the processor
59
   */
60
  Status = XIntc_Start( &InterruptController, XIN_REAL_MODE);
61
  if (Status != XST_SUCCESS) {
62
    return XST_FAILURE;
63
  }
64
65
      /* enable Interrups on Microblaze */
66
      microblaze_enable_interrupts();
67
68
    while(1);
69
   return 0;
70
}

Also, geht das so, mit nur einem GPIO, oder muss ich für jeden 
Druckknopf einen eigenen GPIO nehmen und für jeden einzelne Interrupts 
verlegen?

von Duke Scarring (Gast)


Lesenswert?

olpo schrieb:
>Druckknöpfe
Die werden gepollt. Auch bei FPGAs.
Die Entprellung erfolgt dann meinetwegen in Software.

Tss. Soweit kommt es noch, pro Taster einen Interrupt zu verschwenden...
kopfschüttel

Duke

von Zonk (Gast)


Lesenswert?

schau mal, wie atmel das bei den pinchange interrupts macht...

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.