Zybo > GPIO > 割込み使用 > 動かない > XGpioPs_SetIntrType() / XGpioPs_SetIntrTypePin()

```txt:動作確認
Vivado/XSDK 2015.4
Windows 8.1 pro
Zybo
```

## 実施すること

割込みを使うGPIOの使用を試す。

関連 http://qiita.com/7of9/items/49a069b9e2ae8430b828


## Import Examples

http://qiita.com/7of9/items/373c79ea652db4e69da0
と同様に今度は割込み使用のExampleを試す。

system.mssのps7_gpio_0のImport ExamplesからGPIOのサンプルコードを取込む。xgpiops_intr_exampleを選択した。
hello_bsp_xgpiops_intr_example_1プロジェクトが追加された。


以下のプログラムらしい。

> * The example uses the interrupt capability of the GPIO to detect push button
* events and set the output LEDs based on the input . The user needs to press
* all the switches SW1-SW5 on the evaluation board to exit from this example.


## GPIOの設定

ボタンの設定を以下でやっているようだが、Zyboで動くのだろうか。

```
/* The following constants define the GPIO banks that are used. */
#define INPUT_BANK	XGPIOPS_BANK0  /* Bank 0 of the GPIO Device */
#define OUTPUT_BANK	XGPIOPS_BANK1  /* Bank 1 of the GPIO Device */
```

実行してみたが、Zyboではボタンを押しても何も起こらない。
BANK0,1がMicrozedとZyboで違うのかもしれない。


## XGpioPs_SetIntrType() / XGpioPs_SetIntrTypePin()

[xgpiops.h](https://weble.upc.edu/asig/ESDC/XAPP1026/zc702_GigE/SW/fsbl_bsp/ps7_cortexa9_0/include/xgpiops.h)
にてXGpioPs_SetIntrType()の定義を見ると

```
void XGpioPs_SetIntrType(XGpioPs *InstancePtr, u8 Bank, u32 IntrType,
			  u32 IntrPolarity, u32 IntrOnAny);
```

上記よりXGpioPs_SetIntrType()というのはBankに対しての割込み設定のようだ。

xgpiops.hの違い場所に以下があった。こちらは個別のピンに対して設定できそうだ。

```
void XGpioPs_SetIntrTypePin(XGpioPs *InstancePtr, int Pin, u8 IrqType);
```

引数が異なるので別途情報を探さないといけない。

## code

以下の実装をしたが、動かない。

ポーリングでは動作するが、割込みでは動作しない。

https://www.youtube.com/watch?v=JPVTVNtJ7R4
を参考にVivadoでデザインを作りなおす必要があるのかもしれない。
しかし、ビデオではPS-PL割込みを使っていて、一方、こちらではPSのSW割込みを使いたいだけである。
GPIO用のIPを足す必要があるのだろうか。

```c
#include "xparameters.h"
#include "xgpiops.h"
#include "xscugic.h"
#include "xil_exception.h"
#include <xil_printf.h>

#define GPIO_DEVICE_ID		XPAR_XGPIOPS_0_DEVICE_ID
#define INTC_DEVICE_ID		XPAR_SCUGIC_SINGLE_DEVICE_ID
#define GPIO_INTERRUPT_ID	XPAR_XGPIOPS_0_INTR

#define LED_DELAY 10000000
#define OUTPUT_PIN 7
#define INPUT_PIN  51

#define printf			xil_printf	/* Smalller foot-print printf */

static int GpioIntrExample(XScuGic *Intc, XGpioPs *Gpio, u16 DeviceId,
			   u16 GpioIntrId);
static void IntrHandler(void *CallBackRef, u32 Bank, u32 Status);
static int SetupInterruptSystem(XScuGic *Intc, XGpioPs *Gpio, u16 GpioIntrId);

static XGpioPs Gpio;
static XScuGic Intc;
static u32 AllButtonsPressed = FALSE;

int main(void)
{
	int Status;

	xil_printf("GPIO Interrupt Example Test \r\n");

	Status = GpioIntrExample(&Intc, &Gpio, GPIO_DEVICE_ID,
				 GPIO_INTERRUPT_ID);

	if (Status != XST_SUCCESS) {
		xil_printf("GPIO Interrupt Example Test Failed\r\n");
		return XST_FAILURE;
	}

	xil_printf("Successfully ran GPIO Interrupt Example Test\r\n");
	return XST_SUCCESS;
}

int GpioIntrExample(XScuGic *Intc, XGpioPs *Gpio, u16 DeviceId, u16 GpioIntrId)
{
	XGpioPs_Config *ConfigPtr;
	int Status;

	ConfigPtr = XGpioPs_LookupConfig(DeviceId);
	if (ConfigPtr == NULL) {
		return XST_FAILURE;
	}
	XGpioPs_CfgInitialize(Gpio, ConfigPtr, ConfigPtr->BaseAddr);

	Status = XGpioPs_SelfTest(Gpio);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	XGpioPs_SetDirectionPin(Gpio, INPUT_PIN, 0);

	XGpioPs_SetDirectionPin(Gpio, OUTPUT_PIN, 1);
	XGpioPs_SetOutputEnablePin(Gpio, OUTPUT_PIN, 1);
	XGpioPs_WritePin(Gpio, OUTPUT_PIN, 0); // LED OFF

	Status = SetupInterruptSystem(Intc, Gpio, GPIO_INTERRUPT_ID);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

//	printf("\n\rPush each of the 5 buttons once to exit\n\r");
//	AllButtonsPressed = FALSE;

	while(AllButtonsPressed == FALSE);

	printf("\n\r The GPIO Interrupt example has passed Successfully.\n\r");

	return XST_SUCCESS;
}

static void IntrHandler(void *CallBackRef, u32 Bank, u32 Status)
{
	XGpioPs *Gpio = (XGpioPs *)CallBackRef;
	static u32 ButtonsChanged;
//	volatile int Delay;

	printf("***button pressed***\n\r");

	ButtonsChanged |= Status;

//	XGpioPs_WritePin(Gpio, OUTPUT_PIN, ButtonsChanged);
	XGpioPs_WritePin(Gpio, OUTPUT_PIN, 1);
//	for (Delay = 0; Delay < LED_DELAY; Delay++)
//            ;

}

static int SetupInterruptSystem(XScuGic *GicInstancePtr, XGpioPs *Gpio,
				u16 GpioIntrId)
{
	int Status;
	XScuGic_Config *IntcConfig;

	Xil_ExceptionInit();

	IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
	if (NULL == IntcConfig) {
		return XST_FAILURE;
	}

	Status = XScuGic_CfgInitialize(GicInstancePtr, IntcConfig,
					IntcConfig->CpuBaseAddress);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
				(Xil_ExceptionHandler)XScuGic_InterruptHandler,
				GicInstancePtr);

	Status = XScuGic_Connect(GicInstancePtr, GpioIntrId,
				(Xil_ExceptionHandler)XGpioPs_IntrHandler,
				(void *)Gpio);
	if (Status != XST_SUCCESS) {
		return Status;
	}

//	XGpioPs_SetIntrTypePin(Gpio, INPUT_PIN, XGPIOPS_IRQ_TYPE_EDGE_FALLING);
	XGpioPs_SetIntrTypePin(Gpio, INPUT_PIN, XGPIOPS_IRQ_TYPE_EDGE_RISING);
	XGpioPs_SetCallbackHandler(Gpio, (void *)Gpio, IntrHandler);
	XGpioPs_IntrEnablePin(Gpio, INPUT_PIN);
	XScuGic_Enable(GicInstancePtr, GpioIntrId);
	Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ);


	return XST_SUCCESS;
}
```