1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
| #include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xgpio.h"
#include "xintc.h"
#include "xil_exception.h"
// use two GPIO modules, both with only channel 1
#define GPIO_CHANNEL1 1
#define DIR_OUTPUT 0
#define DIR_INPUT 0x0001
#define INTC_DELAY 2000000
// the width of key_gpio is 1,
// so only the first bit is used.
#define KEY_GPIO_BIT 0x0001
void gpio_handler(void *CallBackRef);
void init_gpio();
void init_gpio_intr();
int Led_on;
int IntrCnt;
XGpio led_gpio;
XGpio key_gpio;
XIntc intc;
int main()
{
init_platform();
init_gpio(); // initialize key and led gpio
init_gpio_intr(); // initialize interrupt
Led_on = 0;
IntrCnt = 0;
print("Receiving key interrupts.\n\r");
while(1){
}
//cleanup_platform();
return 0;
}
void init_gpio()
{
int status;
// XPAR_GPIO_LED_DEVICE_ID: see xparameters.h
// initialize led_gpio as all output
status = XGpio_Initialize(&led_gpio, XPAR_GPIO_LED_DEVICE_ID);
if(status != XST_SUCCESS) //if status!=0
{
printf("Gpio LED Initialization Failed\r\n");
return XST_FAILURE; //return 1
}
XGpio_SetDataDirection(&led_gpio, GPIO_CHANNEL1, DIR_OUTPUT); //all bits as output
//initialize key_gpio as input
status = XGpio_Initialize(&key_gpio, XPAR_GPIO_KEY_DEVICE_ID);
if(status != XST_SUCCESS) //if status!=0
{
printf("Gpio KEY Initialization Failed\r\n");
return XST_FAILURE; //return 1
}
XGpio_SetDataDirection(&key_gpio, GPIO_CHANNEL1, DIR_INPUT); //set the last bit as input
}
void init_gpio_intr()
{
int status;
//initialize the interrupt controller, intc
status = XIntc_Initialize(&intc, XPAR_MICROBLAZE_0_AXI_INTC_DEVICE_ID);
if(status != XST_SUCCESS) //if status!=0
{
printf("INTC Initialization Failed\r\n");
return XST_FAILURE; //return 1
}
/* Hook up interrupt service routine */
XIntc_Connect(&intc, XPAR_INTC_0_GPIO_0_VEC_ID,
(Xil_ExceptionHandler)gpio_handler, &key_gpio);
/* Enable the interrupt vector at the interrupt controller */
XIntc_Enable(&intc, XPAR_INTC_0_GPIO_0_VEC_ID);
/*
* Start the interrupt controller such that interrupts are recognized
* and handled by the processor
*/
status = XIntc_Start(&intc, XIN_REAL_MODE);
if (status != XST_SUCCESS) {
printf("INTC start Failed\r\n");
return XST_FAILURE; //return 1
}
//enable GPIO interrupt for the first bit in key_gpio
XGpio_InterruptEnable(&key_gpio, KEY_GPIO_BIT);
XGpio_InterruptGlobalEnable(&key_gpio);
/*
* Initialize the exception table and register the interrupt
* controller handler with the exception table
*/
Xil_ExceptionInit();
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler)XIntc_InterruptHandler, &intc);
/* Enable non-critical exceptions */
Xil_ExceptionEnable();
}
void gpio_handler(void *CallBackRef)
{
XGpio *GpioPtr = (XGpio *)CallBackRef;
int delay;
IntrCnt ++;
// disable the gpio interrupt for a while
// a very simple key debounce
XGpio_InterruptDisable(&key_gpio, KEY_GPIO_BIT);
for(delay=0;delay < INTC_DELAY; delay++); //introduce some delay
XGpio_InterruptEnable(&key_gpio, KEY_GPIO_BIT);
// toggle the LEDs every time gpio interrupt is triggered
if(Led_on)
{
Led_on = 0;
//GPIO output 0
XGpio_DiscreteWrite(&led_gpio, GPIO_CHANNEL1, 0x00);
}
else
{
Led_on = 1;
//GPIO output 1
XGpio_DiscreteWrite(&led_gpio, GPIO_CHANNEL1, 0x0F);
}
//should use xil_printf() instead of print()
xil_printf("Key pressed count: %d.\n\r", IntrCnt);
/* Clear the Interrupt */
XGpio_InterruptClear(GpioPtr, KEY_GPIO_BIT);
}
|