1 /*
2 * Copyright (c) 2009-2012 Xilinx, Inc. All rights reserved.
3 *
4 * Xilinx, Inc.
5 * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
6 * COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
7 * ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
8 * STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
9 * IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
10 * FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
11 * XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
12 * THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
13 * ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
14 * FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
15 * AND FITNESS FOR A PARTICULAR PURPOSE.
16 *
17 */
18
19 /*
20 * helloworld.c: simple test application
21 *
22 * This application configures UART 16550 to baud rate 9600.
23 * PS7 UART (Zynq) is not initialized by this application, since
24 * bootrom/bsp configures it to baud rate 115200
25 *
26 * ------------------------------------------------
27 * | UART TYPE BAUD RATE |
28 * ------------------------------------------------
29 * uartns550 9600
30 * uartlite Configurable only in HW design
31 * ps7_uart 115200 (configured by bootrom/bsp)
32 */
33
34 #include <stdio.h>
35 #include "platform.h"
36 #include "xgpiops.h"
37
38 #include "xparameters.h"
39 #include "xstatus.h"
40 #include "xscugic.h"
41 #include "xil_exception.h"
42
43 //void print(char *str);
44
45 #define GPIO_DIR 0x0000 /*All work in input mode*/
46 #define GPIO_DEVICE_ID XPAR_XGPIOPS_0_DEVICE_ID // 0
47 #define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID // 0
48 #define GPIO_INTERRUPT_ID XPAR_XGPIOPS_0_INTR // All gpio in four banks to one output (IRQ ID#52) to interrupt controller
49
50
51 /************************** Function Prototypes ******************************/
52
53 static void IntrHandler(void *CallBackRef, int Bank, u32 Status);
54 static int SetupInterruptSystem(XScuGic *Intc, XGpioPs *Gpio, u16 GpioIntrId);
55 int ScuGicInterruptSetup(XScuGic *IntcInstancePtr, u16 DeviceId);
56
57 /************************** Variable Definitions *****************************/
58
59 /*
60 * The following are declared globally so they are zeroed and so they are
61 * easily accessible from a debugger.
62 */
63 static XGpioPs Gpio; /* The Instance of the GPIO Driver */
64
65 XScuGic IntcInstance; /* The Instance of the Interrupt Controller Driver */
66
67 int main()
68 {
69 init_platform();
70
71 print("Hello World\n\r");
72
73 /*****************************************************************/
74 //Set GPIO Interrupt
75 /*****************************************************************/
76 XGpioPs_Config *ConfigPtr;
77 int Status = 0;
78 XGpioPs Gpio;
79 /*
80 * Initialize the Gpio driver.
81 */
82 //printf("Initialize the Gpio driver.\n\r");
83 ConfigPtr = XGpioPs_LookupConfig(GPIO_DEVICE_ID);
84 if (ConfigPtr == NULL) {
85 return XST_FAILURE;
86 }
87
88 XGpioPs_CfgInitialize(&Gpio, ConfigPtr, ConfigPtr->BaseAddr);
89
90 /*
91 * Setup direction register of bank2, so that all the pins are configured as inputs.
92 */
93 //printf("Set gpio direction.\n\r");
94 XGpioPs_SetDirection(&Gpio, 2, GPIO_DIR); // bank2 set to all input
95
96 #ifdef GPIOIOTEST
97 //printf("GPIO bank2 value is 0x%x \n\r",i);
98 // set gpio direction output,'1' for output
99 XGpioPs_SetDirection(&Gpio, 2, 0xff);
100 // set gpio output enable
101 XGpioPs_SetOutputEnable(&Gpio, 2, 0xff);
102 // write value
103 XGpioPs_Write(&Gpio, 2, 0xff);
104 #endif
105
106 /***********************************************************************/
107 /* How to Set Interrupt */
108 /***********************************************************************/
109
110 IntCtl_Init();
111
112 // GPIO is Num.52 interrupt
113 Status = SetupInterruptSystem(&IntcInstance, &Gpio, GPIO_INTERRUPT_ID);
114
115 if (Status != XST_SUCCESS) {
116 print("Set GPIO interrupt Failure \n\r");
117 }
118 else{
119 print("Set GPIO interrupt Successful \n\r");
120 }
121
122 /***********************************************************************/
123
124 while(1)
125 {
126 sleep(5);
127 print("While(1) ing \n\r");
128 }
129
130 return 0;
131 }
132
133
134
135
136
137 /*****************************************************************************/
138 /**
139 *
140 * This function is used by the TestAppGen generated application to setup
141 * the interrupt controller.
142 *
143 * @param IntcInstancePtr is the reference to the Interrupt Controller
144 * instance.
145 * @param DeviceId is device ID of the Interrupt Controller Device,
146 * typically XPAR_<INTC_instance>_DEVICE_ID value from
147 * xparameters.h.
148 *
149 * @return XST_SUCCESS to indicate success, otherwise XST_FAILURE.
150 *
151 * @note None.
152 *
153 ******************************************************************************/
154 int IntCtl_Init(void)
155 {
156 int Status;
157
158 Status = ScuGicInterruptSetup(&IntcInstance, XPAR_PS7_SCUGIC_0_DEVICE_ID);
159 if (Status == 0) {
160 print("ScuGic Interrupt Setup PASSED\r\n");
161 }
162 else {
163 print("ScuGic Interrupt Setup FAILED\r\n");
164 }
165 }
166
167
168
169 /*****************************************************************************/
170 /**
171 *
172 * This function is used by the TestAppGen generated application to setup
173 * the interrupt controller.
174 *
175 * @param IntcInstancePtr is the reference to the Interrupt Controller
176 * instance.
177 * @param DeviceId is device ID of the Interrupt Controller Device,
178 * typically XPAR_<INTC_instance>_DEVICE_ID value from
179 * xparameters.h.
180 *
181 * @return XST_SUCCESS to indicate success, otherwise XST_FAILURE.
182 *
183 * @note None.
184 *
185 ******************************************************************************/
186 int ScuGicInterruptSetup(XScuGic *IntcInstancePtr, u16 DeviceId)
187 {
188
189 int Status;
190 static XScuGic_Config *GicConfig;
191
192 /*
193 * Initialize the interrupt controller driver so that it is ready to
194 * use.
195 */
196 GicConfig = XScuGic_LookupConfig(DeviceId);
197 if (NULL == GicConfig) {
198 return XST_FAILURE;
199 }
200
201 Status = XScuGic_CfgInitialize(IntcInstancePtr, GicConfig, GicConfig->CpuBaseAddress);
202 if (Status != XST_SUCCESS) {
203 return XST_FAILURE;
204 }
205
206 /*
207 * Initialize the exception table.
208 */
209 Xil_ExceptionInit();
210
211
212 /*
213 * Connect the interrupt controller interrupt handler to the hardware
214 * interrupt handling logic in the processor.
215 */
216 Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT,
217 (Xil_ExceptionHandler)XScuGic_InterruptHandler,
218 IntcInstancePtr);
219
220 /*
221 * Enable exceptions.
222 */
223 Xil_ExceptionEnable();
224
225
226 return XST_SUCCESS;
227
228 }
229 /*****************************************************************************/
230 /**
231 *
232 * This function sets up the interrupt system for the example. It enables rasing
233 * edge interrupts for all the pins of bank 2 in the GPIO device.
234 *
235 * @param GicInstancePtr is a pointer to the XScuGic driver Instance.
236 * @param GpioInstancePtr contains a pointer to the instance of the GPIO
237 * component which is going to be connected to the interrupt
238 * controller.
239 * @param GpioIntrId is the interrupt Id and is typically
240 * XPAR_<GICPS>_<GPIOPS_instance>_VEC_ID value from
241 * xparameters.h.
242 *
243 * @return XST_SUCCESS if successful, otherwise XST_FAILURE.
244 *
245 * @note None.
246 *
247 ****************************************************************************/
248 static int SetupInterruptSystem(XScuGic *GicInstancePtr, XGpioPs *Gpio, u16 GpioIntrId)
249 {
250 int Status;
251
252 XScuGic_Config *IntcConfig; /* Instance of the interrupt controller */
253
254 /*
255 * Connect the device driver handler that will be called when an
256 * interrupt for the device occurs, the handler defined above performs
257 * the specific interrupt processing for the device.
258 *
259 *
260 */
261 printf("Connect the device driver handler to interrupt processing \n\r");
262 Status = XScuGic_Connect(GicInstancePtr, GpioIntrId,
263 (Xil_ExceptionHandler)XGpioPs_IntrHandler,
264 (void *)Gpio);
265 if (Status != XST_SUCCESS) {
266 return Status;
267 }
268
269 /*
270 * @param GpioInstancePtr contains a pointer to the instance of the GPIO
271 * component which is going to be connected to the interrupt
272 * controller.
273 * @param set Interrupt Type 0 level ,1 edge
274 * @param Interrupt Polarity 1 rising or high level ,0 falling or low level
275 * @param Interrupt Any Edge Sensitive 0 single edge, 1 both edge
276 * Enable rising edge interrupts for all the pins in bank 2.
277 */
278
279 XGpioPs_SetIntrType(Gpio, 2, 0xffffffff, 0xFFFFFFFF, 0x00); // rising edge only
280
281 /*
282 * Set the handler for gpio interrupts.
283 */
284 printf("Set the handler for gpio interrupts.\n\r");
285 XGpioPs_SetCallbackHandler(Gpio, (void *)Gpio, IntrHandler);
286
287
288 /*
289 * Enable the GPIO interrupts of Bank 2.
290 */
291 printf("Enable the GPIO interrupts of Bank 2.\n\r");
292 XGpioPs_IntrEnable(Gpio, 2, 0xffffffff);
293
294
295 /*
296 * Enable the interrupt for the GPIO device.
297 */
298 printf("Enable the interrupt for the GPIO device. \n\r");
299 XScuGic_Enable(GicInstancePtr, GpioIntrId);
300
301
302 /*
303 * Enable interrupts in the Processor.
304 */
305 printf("Enable interrupts in the Processor \n\r");
306 Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ);
307
308 return XST_SUCCESS;
309 }
310
311
312 /****************************************************************************/
313 /**
314 * This function is the user layer callback function for the bank 0 interrupts of
315 * the GPIO device. It checks if all the switches have been pressed to stop the
316 * interrupt processing and exit from the example.
317 *
318 * @param CallBackRef is a pointer to the upper layer callback reference.
319 * @param Status is the Interrupt status of the GPIO bank.
320 *
321 * @return None.
322 *
323 * @note None.
324 *
325 ******************************************************************************/
326 static void IntrHandler(void *CallBackRef, int Bank, u32 Status)
327 {
328 // Is it necessary to close interrupt ?
329 printf("Enter interrupt \n\r");
330
331 /*
332 * Do nothing if the intr is generated for a different bank.
333 */
334 if (Bank == 2) {
335
336 switch (Status)
337 {
338 // Get interrupt source
339 case 1:
340 printf("The trigger is EMIO GPIO 0 of bank %d \n\r", Bank);
341 break;
342
343 }
344 } else {
345 return;
346 }
347 }