Ultra96-V2 でユーザースイッチからGPIO割り込みを入れてみる（BareMetal編）

# 概要
Xilinx Zynq UltraScale+ MPSoC ZU3EG
で基盤にあるボタンからGPIO割り込みを入れて割り込みハンドラを動作させたときの手順です。
# 事前知識
# 環境構築
## Ultra96ってなに？とかボード、周辺機器準備
こちらの記事 [はじめてのUltra96 必要なもの](https://qiita.com/basaro_k/items/e5654a0061883afea889) がわかりやすいです。
***JTAGのボード、電源も忘れずに買いましょう***
## Ultra96 V2 Hello World
以下のドキュメントでHello Worldまでいけます。（AVNETに登録が必要です）
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540259/38762937-f0b0-73da-7972-aec2859eecae.png" width=100%>
※またボードZYBOで違いますが
[ZYBO (Zynq) 初心者ガイド (1) 開発環境の準備](https://qiita.com/iwatake2222/items/966f252f6ca954aff08b)
こちらの記事が分かりやすいです。HW構成は違いますは基本は同じです。

## FreeRTOS環境


# 割り込みを入れてみる
## HW仕様を調べる
ボードについているボタンを押してGPIO割り込みを入れたいので、まずHW仕様を確認します
http://zedboard.org/sites/default/files/documentations/5365-QSC-ultra96-v2-v3.pdf
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540259/091ac083-9311-70a2-ab49-ff4a804b6bc6.png)
↑の赤いボタンがユーザー用ですね。

で、内部はどのように接続されているかを調べたいので
HW UserGuideを確認します。
http://zedboard.org/product/ultra96-v2-development-board

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540259/25d17d8e-a876-b770-e968-5dd5263e4eb7.png" width=80%>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540259/d2a82ced-7a39-7724-50c4-9dab5839f3e2.png" width=80%>

ボタンは***Bank500 Pin#23*** に対応してそうです。

回路図も確認しましょう
Ultra96-V2 Rev1 Schematic.pdf
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540259/3447d4c0-0b31-1da6-7f8d-c55bc9f7d31b.png)
***Active Low（ボタンを押すと負論理）ですね***


## GPIO割り込みをハンドルするプログラムを書く
### 参考
https://github.com/Xilinx/embeddedsw/blob/master/XilinxProcessorIPLib/drivers/gpiops/examples/xgpiops_intr_example.c
にサンプルプログラムがありました。ただしコメントに
> * This example is to provide support only for zcu102 on ZynqMp Platform and
* only for zc702 on Zynq Platform.

とあるので、こちらをUltra96用にカスタマイズしていきます。

### カスタマイズ
#### define値
```c
/*
 * The following constants map to the names of the hardware instances that
 * were created in the EDK XPS system.  They are defined here such that
 * the user can easily change all the needed device IDs in one place.
 */
#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

/* The following constants define the GPIO banks that are used. */
#define GPIO_BANK	XGPIOPS_BANK0  /* Bank 0 of the GPIO Device */
```
コメントにある通りにXilinx Platform Studio (XPS)では変える必要がなさそうです
https://japan.xilinx.com/products/design-tools/xps.html
ここはこのままとします。

#### 入力Pin
```c
int GpioIntrExample(XScuGic *Intc, XGpioPs *Gpio, u16 DeviceId, u16 GpioIntrId)
{
	XGpioPs_Config *ConfigPtr;
	int Status;
	int Type_of_board;

	/* Initialize the Gpio driver. */
	ConfigPtr = XGpioPs_LookupConfig(DeviceId);
	if (ConfigPtr == NULL) {
		return XST_FAILURE;
	}
	Type_of_board = XGetPlatform_Info();
	switch (Type_of_board) {
		case XPLAT_ZYNQ_ULTRA_MP:
			Input_Pin = 23;
			Output_Pin = 20;
			break;
```
***HW仕様で調べたとおりに Input_Pin を23とします***。
Output_Pinは割り込み動作には無関係なので適当に
Output_Pinに関する制御はコメントアウトしました↓

```c
static void IntrHandler(void *CallBackRef, u32 Bank, u32 Status)
{
	XGpioPs *Gpio = (XGpioPs *)CallBackRef;
	u32 DataRead;

	xil_printf("InitrHandler\n\r");
#if 0
	/* Push the switch button */
	DataRead = XGpioPs_ReadPin(Gpio, Input_Pin);
	if (DataRead != 0) {
		XGpioPs_SetDirectionPin(Gpio, Output_Pin, 1);
		XGpioPs_SetOutputEnablePin(Gpio, Output_Pin, 1);
		XGpioPs_WritePin(Gpio, Output_Pin, DataRead);
		AllButtonsPressed = TRUE;
	}
#endif
}
```
割り込み入ったら分かるようにprint分も追加

#### 割り込み設定
ボタンを押したときに割り込みを入れたいので
・エッジトリガ
・立下り（回路図で確認したようにボタンを押すとGNDに落ちる）
とします。
XGpioPs_SetIntrTypeの3, 4番目の引数で設定できそうです。

>	* @param	IntrType is the 32 bit mask of the interrupt type.
	*		0 means Level Sensitive and 1 means Edge Sensitive.
	* @param	IntrPolarity is the 32 bit mask of the interrupt polarity.
	*		0 means Active Low or Falling Edge and 1 means Active High or
	*		Rising Edge.
	*		
↓のように設定を変更します。

```c
XGpioPs_SetIntrType(Gpio, GPIO_BANK, 0xFFFFFFFF, 0, 0x00);
```

### 実行結果
"InitrHandler" の文字列がボタンを押すたびに表示されました。
静止画は伝わりにくい、、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540259/34790171-ef61-2cad-db09-f084e6c03de0.png)