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?