ZYBO / Pmod > GPIOをPmodコネクタに出力してみた

```txt:動作環境
DIGILENT ZYBO
Vivado 2015.4 on Windows 8.1 pro(64bit)
```

Using Standard Pmod in Zybo Zynq-7000 Development Board
http://hybridcores.com/?p=1
http://hybridcores.com/?p=78

上記を参考にGPIOをPmodコネクタに出力してみた。
ただし、上記の通り実施したら記載通りにならない「はまり」があったので、以下記載のように実施した。

## 関連資料

Pmodコネクタ http://www.marutsu.co.jp/contents/shop/marutsu/datasheet/595400.pdf

## Vivado

### プロジェクト作成

- Project Name: 160709_pmodGPIO
- RTL Project (Do not specify sources at this time はチェックしておく)
- Zybo指定

プロジェクト設定を変更 (リンク元とdesign_1_wrapperファイルが同じ表示になるように)

- [Tool] -> [Porject Settings] -> Generalタブ
  - Target languate: VHDL にする

### Create Block Design  

- Design name: design_1
- add IP: ZYNQ7 Processing System
- Run Block Automation
- add IP: AXI GPIO
- Run Connection Automation (S_AXI選択)

### GPIOのビット設定

- axi_gpio_0をダブルクリックしてRe-customize IPを開く

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/db2e267d-99bb-45cf-44a4-56ce69012966.png)

- Re-customize IPにてIP ConfigurationのところでGPIO widthをPmod コネクタの8出力に合わせて8とする

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/cf298ecc-a8b8-9e4d-0ab3-94c2b3dc00a8.png)

### GPIOポート作成

- GPIO＋の上で右クリックして「Make External」とする
  - GPIOというポートが作成される

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/45ccdf86-51df-6e20-6492-cd49a1bf7e4c.png)

- GPIOというポートをGPIO_Pmodにする (任意)

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/873125cd-ba61-f2d9-090f-17aa529fcde6.png)

### HDL Wrapper作成

- Sourcesウィンドウにおいて、design_1上にて右クリックして「Create HDL Wrapper...」を選択する
  - Let Vivado manager wrapper and auto-update

### 制約ファイルの作成

XDCファイルを作っておく。
ZYBO用にDIGILENTからテンプレートファイルがあるが、ここでは新規作成する。

- Sourcesウィンドウにおいて、Constraints > constrs_1上にて右クリック、「Add Source」選択
- Add or create constraints選択して、Next
- Create Fileをクリック
- File name: pmodGPIO.xdc とした
- FinishをクリックしてAdd Sourcesウィンドウを閉じる

### Run Implementation実行

- Generate Bistreamまで実行してもエラーとなるので、Run Implementationを実行する
- Implementation Completedが表示されたらOpen Implementation Designを選択してOKをクリック
- 画面下のI/O Portsタブを選択して以下のように展開表示する

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/7a28dd74-fe98-b3e7-01df-d6f6f4b18676.png)

### GPIOの設定

上記のI/O Portsに関して以下の3つの設定が必要

1. I/O StdをdefaultからLVCMOS33などの固定値にする
2. SiteにPmodのコネクタのピンを指定する
3. Fixedのチェックをつける

Siteの割り当ては以下のp25に記載の図を参考にする。
http://www.marutsu.co.jp/contents/shop/marutsu/datasheet/595400.pdf

今回はPmod ConnectorのJEを使うこととする。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/289ef801-d6f4-2da4-a2a0-4a27d6585fc9.png)

- 上記参考に以下のように設定する。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/484bcf39-18c8-0b77-30d0-e0ef2867a70d.png)

- Ctrl+Sで保存する
- Out of Date Designというウィンドウが出るのでOKをクリック
- Save Constraintsというウィンドウが出るのでSelect an existing fileを選択してOK
  (新規作成したpmodGPIO.xdcに上書きすることになる)

### XDCファイルの確認

上記によりpmodGPIO.xdcファイルが変更された。

- Open Block Designをクリック
- SourcesのConstraints > constrs_1 > pmodGPIO.xdcを開くと以下のように変更されている

```pmodGPIO.xdc
set_property IOSTANDARD LVCMOS33 [get_ports {gpio_pmod_tri_io[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {gpio_pmod_tri_io[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {gpio_pmod_tri_io[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {gpio_pmod_tri_io[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {gpio_pmod_tri_io[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {gpio_pmod_tri_io[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {gpio_pmod_tri_io[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {gpio_pmod_tri_io[0]}]
set_property PACKAGE_PIN V12 [get_ports {gpio_pmod_tri_io[7]}]
set_property PACKAGE_PIN W16 [get_ports {gpio_pmod_tri_io[6]}]
set_property PACKAGE_PIN J15 [get_ports {gpio_pmod_tri_io[5]}]
set_property PACKAGE_PIN H15 [get_ports {gpio_pmod_tri_io[4]}]
set_property PACKAGE_PIN V13 [get_ports {gpio_pmod_tri_io[3]}]
set_property PACKAGE_PIN U17 [get_ports {gpio_pmod_tri_io[2]}]
set_property PACKAGE_PIN T17 [get_ports {gpio_pmod_tri_io[1]}]
set_property PACKAGE_PIN Y17 [get_ports {gpio_pmod_tri_io[0]}]
```

### Generate Bitstream

- Generate Bitstreamを実行する

### Export

- File > Export > Export Hardware...
  - Include bitstreamチェックしてOKクリック
- File > Launch SDK
  - OKクリック

## XSDK

### プロジェクト作成

- File > New > Application Project
  - Project name: gpioPmod
  - Nextクリック
  - Hellow Worldを選択してFinish

### ソース

gpioPmod > src > helloworld.cを以下のように書換える。

```helloworld.c
#include <stdio.h>
#include "xparameters.h"
#include "xgpio.h"
#include "platform.h"

#define PMOD_DEVICE_ID  XPAR_AXI_GPIO_0_DEVICE_ID

XGpio PMODInst;

int main()
{
    init_platform();

    print("Hello World\n\r");

    int status;
    status = XGpio_Initialize(&PMODInst, PMOD_DEVICE_ID);
    if (status != XST_SUCCESS) {
        print("PMOD GPIO initialize failure\r\n");
        return -1;
    }
    XGpio_SetDataDirection(&PMODInst, 1, 0); // 2つ目の引数は1
    XGpio_DiscreteWrite(&PMODInst, 1, 0x0F); // 2つ目の引数は1. Pmod 下段だけON

    while(1) {

    }

    cleanup_platform();
    return 0;
}
```

### 実行

- TeraTermなどを立ち上げて115200bpsにしておく
- ZYBOの電源投入
- メニュー Xilinx Tools > Program FPGA > Programをクリック
- Project ExplorerのgpioPmod > Binaries > gpioPmod.elf上で右クリックして、Run As > 1. Launch on Hardware (System Debugger)で実行する
  - TeraTermにHello Wolrdが表示され、Pmod JEコネクタに電圧が立っている。

### 電圧の立つところ

http://www.marutsu.co.jp/contents/shop/marutsu/datasheet/595400.pdf
の以下の図参照。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/4cf6e5ee-e46d-25eb-3e30-65709e159d62.png)

```
    XGpio_DiscreteWrite(&PMODInst, 1, 0x0F);
```
の場合、2段のうち下段だけが3.3V立つ。上段は0Vになる。

両段を3.3V立たせるには以下のようにする。

```
    XGpio_DiscreteWrite(&PMODInst, 1, 0xFF);
```

あとは0xFFの値を変更することで、任意のビットを立たせたり落としたりできる。

### XGpio_DiscreteWrite()の引数

XGpio_DiscreteWrite(&PMODInst, 1, 0x0F);
の2つめの引数は1にすること。

これが分からず「はまって」しまった。

なひたふさんの記事が参考になった。
http://nahitafu.cocolog-nifty.com/nahitafu/2013/07/zynqpspl4-gpio-.html


ようやくPmodで外界との接続ができるようになった。ファーストコンタクト成功!